Django Rest 框架:XMLHttpRequest 无法加载 http://127.0.0.1:8000/xyz/api/abc

Posted

技术标签:

【中文标题】Django Rest 框架:XMLHttpRequest 无法加载 http://127.0.0.1:8000/xyz/api/abc【英文标题】:Django Rest Framework: XMLHttpRequest cannot load http://127.0.0.1:8000/xyz/api/abc 【发布时间】:2016-01-27 07:49:33 【问题描述】:

解决方案:在网址末尾添加一个斜杠...

“http://127.0.0.1:8000/xyz/api/abc/”而不是“http://127.0.0.1:8000/xyz/api/abc”

....

我已经成功创建了一个 Django Rest API,并且似乎能够在本地存储和托管数据。我已经单独构建了一个 angularjs1.0 应用程序并试图通过 $http get 请求提取数据但是我遇到了这个错误:

XMLHttpRequest cannot load http://127.0.0.1:8000/xyz/api/abc. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://172.20.9.163:8080' is therefore not allowed access.

我已尝试安装 CORS 并将其添加到我的 INSTALLED_APPS,但似乎还没有任何效果。

这是获取请求:

getABC : function() 
            $http(
                method: 'GET',
                url: 'http://127.0.0.1:8000/xyz/api/abc',
                cache: false
            ).success(function(data) 
                console.log(data)
                callback(data);
            );
        ,

看看我的 Django settings.py 文件:

INSTALLED_APPS = (
    'xyz',
    'corsheaders',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

)

CORS_ORIGIN_ALLOW_ALL = True

【问题讨论】:

您可以在开发工具中打开网络选项卡并检查对您的 AJAX 请求的响应吗?它实际上是否包含Access-Control-Allow-Origin 标头? 抱歉,我应该在哪里看到这个?我打开了网络选项卡,但在任何地方都看不到 ajax 请求响应。 @IgorRaush“远程地址:127.0.0.1:8000 请求 URL:127.0.0.1:8000/xyz/api/abc 请求方法:获取状态代码:301 永久移动(从缓存中)”当点击“响应”选项卡时,它说“此请求没有可用的响应数据。” 有什么问题。您的 API 正在返回重定向响应。该响应是否有Location 标头?你能从命令行运行curl --head http://localhost:8000/xyz/api/abc吗? 另外,似乎请求甚至可能无法到达服务器,它在浏览器中缓存为301 Moved Permanently... 【参考方案1】:

安装 django-crops-headers

pip install django-cors-headers

在setting.py中:

MIDDLEWARE = [
             #...
                 'corsheaders.middleware.CorsMiddleware',
                 'django.middleware.common.CommonMiddleware',
             ]
INSTALLED_APPS = [

                'corsheaders',
                 #...
                ]

设置 CORS_ORIGIN_ALLOW_ALL 为真

CORS_ORIGIN_ALLOW_ALL = True  # this allows all domains

Or to allow specific domains 

CORS_ORIGIN_WHITELIST = (
'http://example.com',
'http://127.0.0.1:8000',
'http://localhost:8000',
 )

在 Ajax 调用(前端)中添加标头:

 var get_request = $.ajax(
  type: 'GET',
  "headers": 
          "accept": "application/json",
          "Access-Control-Allow-Origin":"*"
      ,
  url: 'http://example.com',
);

如果没有解决,请在请求服务器中启用核心(http://example.com)

【讨论】:

【参考方案2】:

TL;DR

向附加斜杠的 URL 发出 AJAX 请求。

说明

经过我们的讨论,罪魁祸首似乎是 Django 的自动APPEND_SLASH = True,它在启用CommonMiddleware 时启用。

这会导致来自 Angular 应用程序的 AJAX 请求首先命中 301 Moved Permanently 重定向到附加斜杠的 URL。但是,corsheaders 中间件不会对此响应采取行动,因此浏览器会抱怨缺少 Access-Control-Allow-Origin 标头。

这可以通过直接请求附加斜杠的 URL 来解决,完全绕过 301 重定向。

$http(
    method: 'GET',
    url: 'http://127.0.0.1:8000/xyz/api/abc/',  // trailing slash here
    cache: false
).success(...);

【讨论】:

以上是关于Django Rest 框架:XMLHttpRequest 无法加载 http://127.0.0.1:8000/xyz/api/abc的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest 框架的 ModuleNotFoundError

带有 Django 2.0 的 Django REST 框架 URL

Django REST框架 -1

django.test.client 上的 Django rest 框架导入错误

Django Rest 框架令牌认证

使用 django-allauth 和 django-rest 框架