内容简介:本篇提供几个例子,从代码层面说明同源政策何时起作用,并尝试通过几种不同的方法解决跨域问题。此处需要注意的是,若127.0.0.1换成localhost则该请求会被同源政策禁止。即,localhost与127.0.0.1被认为是不同源的。此时,我们再启一个flask项目,端口定在5000,使上面4000端口的ajax去此项目取数据。
本篇提供几个例子,从代码层面说明同源政策何时起作用,并尝试通过几种不同的方法解决跨域问题。
同源下可Ajax成功
# -*- coding: utf-8 -*- from flask import Flask app = Flask(__name__) content = ''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> var xhr = new XMLHttpRequest(); // 指定通信过程中状态改变时的回调函数 xhr.onreadystatechange = function(){ // 通信成功时,状态值为4 if (xhr.readyState === 4){ if (xhr.status === 200){ document.body.innerHTML = xhr.responseText } else { document.body.innerHTML = xhr.statusText } } }; xhr.onerror = function (e) { console.error(xhr.statusText); }; // open方式用于指定HTTP动词、请求的网址、是否异步 xhr.open('GET', 'http://127.0.0.1:4000/get_data', true); // 发送HTTP请求 xhr.send(null); </script> </body> </html> ''' @app.route("/") def hello(): return content @app.route('/get_data') def get_data(): return 'got data!' if __name__ == '__main__': app.run(port=4000)
先是第一版,一个简单的flask程序。
打开浏览器输入:http://127.0.0.1:4000会返回字符串回去,交给浏览器,其解析运行其中的javascript代码,发出ajax请求,至同服务下的/get_data路由,得到数据后渲染至页面。
结果为:
此处需要注意的是,若127.0.0.1换成localhost则该请求会被同源政策禁止。即,localhost与127.0.0.1被认为是不同源的。
不同源时Ajax不成功
此时,我们再启一个flask项目,端口定在5000,使上面4000端口的ajax去此项目取数据。
# -*- coding: utf-8 -*- from flask import Flask app = Flask(__name__) @app.route("/get_data_5000") def hello(): return "got data in 5000!" if __name__ == '__main__': app.run(port=5000)
得到如下结果:
显然,由于端口号已经不一致,违反了同源政策,请求失败。
使用应用层第三方包
在应用层,使用第三方包增加http response header的方式来处理。
5000项目变为:
# -*- coding: utf-8 -*- from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app)
重启项目后,访问http://127.0.0.1:4000即可拿到5000的数据。
可以看到第三方包自动处理了response header。
此处不只是flask,不只是python,各个语言,各种web框架,都可以在这一层通过第三方包的形式来处理跨域问题,如果找不到相关插件,大不了自己写一个好喽。
代理屏蔽
此时要Nginx上场了。
思路是,启项目于4000和5000端口,浏览器不直接通过端口访问web服务,而是通过Nginx的80端口,Nginx将实际上有两个项目这件事情对浏览器屏蔽掉。
改Nginx配置为:
server { listen 80; server_name localhost; location / { proxy_pass http://127.0.0.1:4000; } location /get_data_5000 { proxy_pass http://127.0.0.1:5000/get_data_5000; } }
然后去掉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。
在 这里 抄一下配置。
location /get_data_5000 { proxy_pass http://127.0.0.1:5000/get_data_5000; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # Custom headers and headers various browsers *should* be OK with but aren't # add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; # # Tell client that this pre-flight info is valid for 20 days # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; } }
配置中可写if,可按需要操作header,结果如下:
OK, Well done!
以上所述就是小编给大家介绍的《解决跨域问题代码示例》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 怎么写 Java 示例代码?
- SpringJDBC批量处理数据代码示例
- 前端基本功-示例代码(一)
- 前端基本功-示例代码 (二)
- golang语言爬虫代理代码示例
- flex actionScript读取文件示例代码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Netty实战
诺曼·毛瑞尔(Norman Maurer)、马文·艾伦·沃尔夫泰尔(Marvin Allen Wolfthal) / 何品 / 人民邮电出版社 / 2017-5-1 / 69.00
编辑推荐 - Netty之父”Trustin Lee作序推荐 - 阿里巴巴中间件高级技术专家为本书中文版作序推荐 - 系统而详细地介绍了Netty的各个方面并附带了即用型的优质示例 - 附带行业一线公司的案例研究 - 极实用的Netty技术书 无论是构建高性能的Web、游戏服务器、推送系统、RPC框架、消息中间件还是分布式大数据处理引擎,都离不开Nett......一起来看看 《Netty实战》 这本书的介绍吧!
HTML 压缩/解压工具
在线压缩/解压 HTML 代码
正则表达式在线测试
正则表达式在线测试