使用React调用REST API时出现CORS错误

Che*_*neZ 4 django rest cors django-rest-framework reactjs

我使用此URL http://192.168.33.10:8002/scenarios/创建了一个可以使用django-rest-framework创建的restful api,我正在创建一个React应用程序来调用api并消耗其数据.

我正在使用fetch来调用api

componentWillMount: function(){
 this.setState({Problemstyle: this.props.Problemstyle})
 fetch('http://192.168.33.10:8002/scenarios/')
 .then(result=>result.json())
 .then(result=> {
   this.steState({items:result})
 })
 },
Run Code Online (Sandbox Code Playgroud)

当我运行我的应用程序时,我的浏览器出错

Fetch API无法加载http://192.168.33.10:8002/scenarios/.请求的资源上不存在"Access-Control-Allow-Origin"标头.因此不允许来源" http://192.168.33.10:8001 ".如果不透明响应满足您的需求,请将请求的模式设置为"no-cors"以获取禁用CORS的资源.

我不确定如何解决这个问题,因为我刚刚开始使用React

Tim*_*Tim 15

当前接受的答案可能会使网站面临安全风险:

为什么会发生错误:

为了让您的 AJAX 请求正常工作,需要做两件事:

  1. 服务器必须接受请求。
  2. 返回的请求必须被浏览器接受,以便客户端可以对其进行处理。

OP 报告的错误表明此过程的第二部分失败。这是因为如果请求是从与返回请求的服务器不同的域发送的,浏览器将不会接受它,除非设置了适当的标头(即,服务器已授予浏览器读取它的权限)。

如何修复:

现在要解决这个问题,我们可以使用django-cors-headers. 这将添加适当的标头,以便浏览器接受返回的响应。要安装运行:

pip install django-cors-headers
Run Code Online (Sandbox Code Playgroud)

并将其添加到您的中间件中:

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]
Run Code Online (Sandbox Code Playgroud)

现在,您需要将发送 AJAX 请求的域添加到允许域列表中:

CORS_ALLOWED_ORIGINS = [
    "www.example.com",
    "http://127.0.0.1:8000",
    ...
]
Run Code Online (Sandbox Code Playgroud)

怎么样CORS_ORIGIN_ALLOW_ALL

除非您有特殊需要,否则不要使用它。将此设置为 true,意味着任何来源都可以向您的 API 发出请求,并获得响应。除非您正在制作公共 API,否则您可能不需要这样做。更有可能您只需要为单个域或几个域提供服务(也许您有一个前端,从不同的地方提供给您的 API 等)

如果你幸福的任何域名访问你的API,那么你可以设置如下:

CORS_ORIGIN_ALLOW_ALL = True
Run Code Online (Sandbox Code Playgroud)

如果您这样做,您还需要设置以下内容:

ALLOWED_HOSTS = ['*']
Run Code Online (Sandbox Code Playgroud)

这样做的原因是 Django 默认只接受某些主机,所以CORS_ORIGIN_ALLOW_ALL = True除非你真的要接受任何人的请求(这是上面解释的第 1 部分),否则没有意义设置。

请注意,通过将允许的主机设置为通配符,您将面临 HTTP 主机标头攻击。请确保您了解这些内容,并确保您不受影响。您可以在 django 文档中阅读有关它们的更多信息。

另请注意:如果您没有设置您的ALLOWED_HOSTS并且您想知道为什么您的请求有效,那是因为当DEBUG=True某些主机被自动允许时,http://127.0.0.1:8000等等。


zai*_*zil 12

通过安装django-cors-headers pip install django-cors-headers

然后,添加已安装的应用程序'corsheaders'.

添加设置,

CORS_ORIGIN_ALLOW_ALL = True
Run Code Online (Sandbox Code Playgroud)

和,

ALLOWED_HOSTS = ['*']
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题.

UPDATE

您还需要将其添加到中间件中,

MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]
Run Code Online (Sandbox Code Playgroud)

  • 请停止发布安全问题的解决方案,它甚至不是一个解决方案,它是一个非常重要的安全方面的解决方法。@zaidfazil我建议你删除你的答案或至少编辑说“请这只是为了展示如何不这样做” (2认同)