Access-Control-Allow-Origin跨域问题
日常开发中,特别是如今,前后端分离甚至是前后端不同域,这种情况下进行数据交换就会出现跨域问题。
Cross-Origin Resource Sharing
是允许客户端与托管在不同域上的API
交互的机制。CORS
的工作原理是要求服务器包含一组特定的标头信息,允许浏览器确定是否和何时允许跨域请求。
ajax
无法访问django
接口
一般出现这种情况的很大可能是出现在本地开发环境,甚至有可能使用pycharm
运行django
导致的。本人刚遇到这种问题也是一脸懵逼,麻蛋,浏览器正常访问,怎么一用ajax
就直接走error
方法出现network error
,百度了很久仍然没有遇到跟我一样情况的,感觉是跨域问题,愣是没找到解决办法,想来想去,终于毛瑟顿开。
分析下,正常pycharm
运行我们的django
项目是默认走得80端口,使用127.0.0.1
。问题就是出现在这个ip
上。
127.0.0.1
是回送地址,localhost
是本地DNS
解析的127.0.0.1
的域名,在hosts
文件里可以看到。
一般我们通过ping 127.0.0.1
来测试本地网络是否正常。其实从127.0.0.1~127.255.255.255
,这整个都是回环地址。这边还要
注意的一点就是localhost
在了IPV4
的是指127.0.0.1
而IPV6
是指::1
。当我们在服务器搭建了一个web服务
器的时候如果我们
监听的端口时127.0.0.1:端口号
的 时候,那么这个web
服务器只可以在服务器本地访问了,在别的地方进行访问是不行的。
(127.0.0.1
只可以在本地ping
自己的,那么你监听这个就只可以在本地访问了)
然后我们来讲讲0.0.0.0
,如果我们直接ping 0.0.0.0
是不行的,他在IPV4
中表示的是无效的目标地址,但是在服务器端它表示
本机上的所有IPV4
地址,如果一个服务有多个IP
地址(192.168.1.2
和10.1.1.12
),那么我们如果设置的监听地址是0.0.0.0
那
么我们无论是通过IP192.168.1.2
还是10.1.1.12
都是可以访问该服务的。在路由中,0.0.0.0
表示的是默认路由,即当路由表中没有找到完全匹配的路由的时候所对应的路由。
如果以上内容把你说晕了,那么你就直接记住相让别人可以访问你那就绑定在0.0.0.0
上,反之绑定在127.0.0.1
上
所以修改下你的项目运行属性
再次测试已经可以正常取到接口数据了,但是也许你会遇到下面这个新的问题。
跨域问题
1 | Access to XMLHttpRequest at 'http://aaa.com/api/' from origin 'http://bbb.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. |
如果你的网站控制台出现了以下提示,很荣幸告诉你,你遇到跨域问题了。
Django REST framework
官方文档中是这样描述关于跨域问题的,同时官方也给出了两种解决方案:
使用中间件
在REST
框架中处理CORS
的最佳方法是在中间件中添加所需的响应头信息。这样可以确保CORS
得到透明支持,而无需更改视图中的任何行为。
1 | # cors_middleware.py |
使用第三方包
Otto Yiu
维护着能在REST
框架搭建的API
下正常使用的django-cors-headers
包。
安装第三方包
1 | pip install django-cors-headers |
配置安装包
1 | INSTALLED_APPS = [ |
配置中间件
1 | MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10 |
配置settings
1 | CORS_ORIGIN_ALLOW_ALL = True # 允许任何域访问 |
其他常用参数
1 | # 在某些url上使用这个跨域中间件 |