最近在用前端框架写 的时候遇到跨域请求的问题。可能对很多人来说这个问题并不新鲜,可我以前并没有去深入了解,借这个机会总结一下。
为什么会有跨域请求问题?
一个网站可能包含网页,API,以及各种资源文件(css, js, , fonts)等等,而这些可能会在不同的域名下。以 *. 为例,www 是网页,api 是接口, 是各种资源文件。 如果在网页中嵌入 web fonts,或者使用 AJAX 跨域请求时,在同源策略的约束下,这种请求返回会被禁止。
如何解决跨域请求?
事实上,为了解决因同源策略而导致的跨域请求问题,解决方法有五种:
.
Cross- (CORS)
Cross-
CORS 定义了一种浏览器和服务器之间是否允许跨站请求的标准。这种方式相对其它的来说更加灵活简单,也是 W3C 推荐的方法。
CORS 是如何工作的?
CORS 标准定义了一组新的 HTTP ,这组 给浏览器和服务器提供了一种判断跨域请求是否何法的依据。 因此,要实现 CORScors跨域,浏览器()和服务器()都应该遵守该约定。
浏览器端需要在请求的时候增加一个 的 HTTP ,值为当前页面的域()。如: 的页面要请求 的资源,需带上的 HTTP 为 : 。
服务器端接收请求,返回的时候需要返回一个 --Allow- 的 表明哪个域是允许的,如果全都允许,可以使用 * 号。如上例, 的返回需要带上 --Allow-: 。
服务器端解决方案
几乎所有框架都有现成的库可用,以下只列举我用过的三种:
Ruby (Rails, , etc)
所有基于 Rack 的 Ruby 框架都可以使用 rack-cors。文档非常详细cors跨域,不再累述。
Flask
Flask 也有一个插件 flask-cors,但是文档很差, 社区通病。
// 1. 安装$ pip -U flask-cors
// 2. app.py from flask.ext.cors CORS
app = Flask()CORS(app)
CORS(app) 方法可接收很多 而文档并没有给出,其中比较常用的几个:
:True 返回 *;False 则返回 的值
:是否允许访问 , 默认为 False
:可作用的范围,默认为 r'/*';如只允许 /api/* 开头的 URL,则 =r'/api'
Nginx
Nginx 只需要修改对应 的配置文件
更完整的配置参考这个 Gist: