解决跨域问题代码示例
本篇提供几个例子,从代码层面说明同源政策何时起作用,并尝试通过几种不同的方法解决跨域问题。
同源下可Ajax成功
先是第一版,一个简单的flask程序。自己请求自己,不会有什么问题。
打开浏览器输入:http://127.0.0.1:4000
会返回字符串回去,交给浏览器,其解析运行其中的javascript代码,发出ajax请求,至同服务下的/get_data路由,得到数据后渲染至页面。
代码如下:
1 | # -*- coding: utf-8 -*- |
结果为:
此处需要注意的是,若127.0.0.1换成localhost则该请求会被同源政策禁止。
不同源时Ajax不成功
此时,我们再启一个flask项目,端口定在5000,修改上面代码中xhr open的地址,使4000端口的ajax去5000取数据。
1 | # -*- coding: utf-8 -*- |
得到如下结果:
显然,由于端口号已经不一致,违反了同源政策,请求失败。
使用应用层第三方包
在应用层,使用第三方包增加http response header的方式来处理。
5000项目变为:
1 | # -*- coding: utf-8 -*- |
重启项目后,访问http://127.0.0.1:4000
即可拿到5000的数据。
可以看到第三方包自动处理了response header。
此处不只是flask,不只是python,各个语言,各种web框架,都可以在这一层通过第三方包的形式来处理跨域问题,如果找不到相关插件,大不了自己写一个好喽。
代理屏蔽
此时要Nginx上场了。
思路是,启项目于4000和5000端口,浏览器不直接通过端口访问web服务,而是通过Nginx的80端口,Nginx将实际上有两个项目这件事情对浏览器屏蔽掉。
改Nginx配置为:
1 | server { |
然后去掉flask-cors插件,再将4000中的ajax url改为http://127.0.0.1/get_data_5000
。
效果如图:
可以看到,此时不再需要response header中的Access-Control-Allow-Origin即可请求到另一个项目的服务。
这种处理方法可以联想到设计模式中的facade模式,此时Nginx即为外观层,后面到底有多少个项目在提供服务,请求者不需要关心。
不过这种方式是有一定局限性的,即只有这个Nginx可导向的服务才可不受跨域问题影响。
Nginx配置Header
移除之前的Nginx配置,通过4000端口访问页面,将5000端口的项目通过Nginx访问,并在Nginx这一层,来处理response header。
在这里抄一下配置。
1 | location /get_data_5000 { |
配置中可写if,可按需要操作header,结果如下:
OK, Well done!
Author: Guerbai
Link: http://guerbai.github.io/2018/01/05/solve-cross-origin-code/
License: 知识共享署名-非商业性使用 4.0 国际许可协议