AJAX跨域简单讲解【Python版】

前端之家收集整理的这篇文章主要介绍了AJAX跨域简单讲解【Python版】前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

总结自慕课网:ajax跨域完全讲解,并且原视频中后台JAVA,这里改成了Python


什么是AJAX跨域

只要协议、域名、端口有任何一个不同,都被当作是不同的域,不同域之间的请求就是跨域操作。AJAX跨域就是AJAXA域下对B域发送了请求,一般情况下会被浏览器禁止

例如,后台开启两个Flask服务器ServerA(port=8080)ServerB(port=8081)
ServerA.py代码如下:

  1. from flask import Flask,render_template
  2.  
  3. app = Flask(__name__)
  4.  
  5.  
  6. @app.route('/')
  7. def index():
  8. return render_template('index.html')
  9.  
  10.  
  11. @app.route('/get')
  12. def get():
  13. return 'get8080 ok'
  14.  
  15. if __name__ == "__main__":
  16. app.run(port=8080)

ServerB.py代码如下:

  1. from flask import Flask
  2.  
  3. app = Flask(__name__)
  4.  
  5.  
  6. @app.route('/get')
  7. def get():
  8. return 'get8081 ok'
  9.  
  10. if __name__ == "__main__":
  11. app.run(port=8081)

index.html使用jQuery发送ajax请求,代码如下:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Index</title>
  5. </head>
  6. <body>
  7. <h3>Test</h3>
  8. <button onclick="get1()">GET 8080</button>
  9. <button onclick="get2()">GET 8081</button>
  10. </body>
  11. <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  12. <script type="text/javascript">
  13. function get1(){
  14. $.get("http://127.0.0.1:8080/get").then(
  15. function(res){
  16. console.log(res);
  17. })
  18. }
  19. function get2(){
  20. $.get("http://127.0.0.1:8081/get").then(
  21. function(res){
  22. console.log(res);
  23. })
  24. }
  25. </script>
  26. </html>

因此GET 8080GET 8081两个按钮是分别向8080/8081端口发送请求,并将结果打印在控制台。开启两个服务器,在浏览器输入127.0.0.1:8080进入index页面,打开Chrome控制台并依次点击,结果如图:

可以看到GET 8080正常输出,而由于8081端口的请求属于跨域,浏览器报错并未正常打印结果。


如何处理AJAX跨域问题

1.关闭浏览器安全策略

禁止跨域的AJAX请求,是浏览器本身的安全策略,实际上后台并没有限制,例如点击GET 8081后,可以在NETWORK中看到这个请求本身是OK的:

因此只要关闭浏览器的安全策略即可,方式之一是在命令行中使用

  1. "chrome.exe路径" --disable-web-security --user-data-dir=D:\temp

打开浏览器,此时浏览器会有安全性提示,依次点击两个按钮,结果如图:

2.使用JSONP

AJAX请求受到跨域的限制,其请求类型是xhr,但html页面在引用别的域的JS脚本时却可以正常访问,这种请求的类型是script,如图:

JSONP的原理就是将原本的xhr请求替换为script请求,例如假设原先xhr请求返回的是数据AJSONP请求会附带一个callback参数说明本地使用的回调函数,假设为func1,后端收到这个JSONP请求,返回的是JS代码func1(A)。使用JSONP需要对前后端都做修改。在此不演示~

3.在ServerA修改

我们可以让后台服务器代替浏览器去请求跨域的接口,并将数据通过本域的接口返回给浏览器,使浏览器不再发送跨域请求。例如在ServerA.py增加一个接口如下:

  1. @app.route('/get_8081_through_8080')
  2. def get2():
  3. return requests.get('http://127.0.0.1:8081/get').text

index.html增加一个button,如下:

  1. <button onclick="get3()">GET 8081 THROUGH 8080</button>
  2.  
  3. <script type="text/javascript">
  4. function get1(){
  5. ...
  6. }
  7. function get2(){
  8. ...
  9. }
  10. function get3(){
  11. $.get("http://127.0.0.1:8080/get_8081_through_8080").then(
  12. function(res){
  13. console.log(res);
  14. })
  15. }
  16. </script>

此时对浏览器而言get3()就不属于跨域的请求了,后台代替浏览器向8081发送了请求。
结果如图所示,第二个button由于跨域仍然报错,第三个button则正常输出

4.在ServerB修改

ServerB也可以通过向浏览器返回特定响应头,告诉浏览器它是允许被跨域调用的,使用flaskmake_response添加Access-Control-Allow-OriginAccess-Control-Allow-Methods两个字段,ServerB.py更新如下:

  1. from flask import Flask,Response
  2. app = Flask(__name__)
  3.  
  4. @app.route('/get')
  5. def get():
  6. return 'get8081 ok'
  7.  
  8. @app.route('/get2')
  9. def get2():
  10. resp = Response('get8081 ok by Access-Control-Allow')
  11. resp.headers['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8080'
  12. resp.headers['Access-Control-Allow-Methods'] = 'GET'
  13. return resp
  14.  
  15.  
  16. if __name__ == "__main__":
  17. app.run(port=8081)

index.htmlget2()方法请求的接口改为'http://127.0.0.1:8081/get2',依次点击button,第二个button已经可以正常输出内容

猜你在找的Ajax相关文章