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

时间:2017-05-18 02:13:26

标签: django rest reactjs cors django-rest-framework

我使用此网址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})
 })
 },

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

  

Fetch API无法加载http://192.168.33.10:8002/scenarios/。 No' Access-Control-Allow-Origin'标头出现在请求的资源上。起源' http://192.168.33.10:8001'因此不允许访问。如果不透明的回复符合您的需求,请将请求的模式设置为“无人”状态。在禁用CORS的情况下获取资源。

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

3 个答案:

答案 0 :(得分:9)

通过pip install django-cors-headers

安装django-cors-headers

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

添加设置

CORS_ORIGIN_ALLOW_ALL = True

和,

ALLOWED_HOSTS = ['*']

这应该可以解决问题。

<强>更新

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

MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

答案 1 :(得分:6)

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

为什么会发生错误:

为了使您的AJAX请求正常工作,需要发生两件事:

  1. 该请求必须由服务器接受。
  2. 返回的请求必须被浏览器接受,以便客户端可以执行某些操作。

OP报告的错误,表明该过程的第二部分失败。这是因为,如果请求是从与返回请求的服务器不同的域发送的,则除非设置了适当的标头(即 server 已授予在浏览器中阅读)。

如何修复:

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

pip install django-cors-headers

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

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

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

CORS_ORIGIN_WHITELIST = [
    "www.example.com",
    "http://127.0.0.1:8000",
    ...
]

CORS_ORIGIN_ALLOW_ALL呢?

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

如果您很高兴允许任何域访问您的API,则可以设置以下内容:

CORS_ORIGIN_ALLOW_ALL = True

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

ALLOWED_HOSTS = ['*']

之所以这样,是因为Django默认情况下将仅接受某些主机,因此没有任何设置CORS_ORIGIN_ALLOW_ALL = True,除非您实际上要接受任何人的请求(这是上面说明的第1部分)

请注意,通过将允许的主机设置为通配符,可以对HTTP主机头攻击开放。确保您了解这些内容,并确保您没有受到影响。您可以阅读有关in the django docs的更多信息。

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

答案 2 :(得分:2)

使用 django-cors-headers

首先使用 pip 安装 django-cors-headers

pip install django-cors-headers

您需要将其添加到您的项目 settings.py 文件中:

INSTALLED_APPS = (
    ##...
    'corsheaders'
)

接下来需要将 corsheaders.middleware.CorsMiddleware 中间件添加到 settings.py 中的中间件类中

MIDDLEWARE_CLASSES = (
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.BrokenLinkEmailsMiddleware',
    'django.middleware.common.CommonMiddleware',
    #...
)

然后,您可以通过添加以下设置为所有域启用 CORS

CORS_ORIGIN_ALLOW_ALL = True

或者只为指定域启用 CORS:

CORS_ORIGIN_ALLOW_ALL = False

CORS_ORIGIN_WHITELIST = (
    'http//:localhost:8000',
)