同源策略以及跨域访问


声明:本文转载自https://my.oschina.net/u/3688629/blog/1560497,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

1.同源策略又名同域策略,就是(主机名+协议+端口号【若存在】)三者相同。也就是说javascript只可以操作自己域下的东西,不能操作其他域下的东西。比如百度下javascript是不可操作谷歌下的页面;

在浏览器中,<script>、<img>、<iframe>、<link>等标签都可以加载跨域资源,而不受同源限制,但浏览器限制了JavaScript的权限使其不能读、写加载的内容。

同源策略只对网页的HTML文档做了限制,对加载的其他静态资源如javascript、css、图片等仍然认为属于同源。

2.使用ajax必须满足同源策略;在本地hosts文件配置两个域名访问IP作为测试用

127.0.0.1 www.fwd.com 
127.0.0.1 www.khd.com

在 http://www.khd.com:8002/khd 文件里用ajax请求http://www.fwd.com:8001/fwd(jquery)

请求页面(jquery):

<input type="button" value="提交" onclick="doajax();"/> <script>     function doajax() {         $.ajax({             url: 'http://www.fwd.com:8001/fwd',             type: 'POST',             data:{'k1':'v1'},             success: function (responseText, statusText) {             },             error: function (event, errorText, errorType) {              }         });     } </script>

此时点击按钮发起ajax请求后,可以看到请求已被浏览器的同源策略阻止。
3.  突破浏览器同源策略ajax跨域请求,有两个办法:

法一、JSONP方式

自定义JSONP跨域请求数据只能是get方法的请求,也就是利用script标签和script标签的src发送get请求

1在要请求数据的页面用js创建一个script标签,src等于要请求数据的地址

2响应页面返回的必须是一个带有参数的函数名称

3自定义对应响应页面返回的函数,这样自定义的函数也就会执行了,就能得到数据

请求页面(原生js):

<input type="button" value="跨域提交" onclick="doajax();"/> <script>     //利用原生js自己创建一个跨域请求     function doajax() {                                 //当点击提交按钮是执行函数         var tag = document.createElement('script');     //创建一个script标签         tag.src = 'http://www.fwd.com:8001/fwd';        //设置script标签的src地址,为要请求数据的地址,因为src是不受同源策略         document.head.appendChild(tag);                 //将script标签添加到head标签里面         document.head.removeChild(tag);                 //添加后会立即发送请求,所以这里可以将添加的script标签删除了     }     //响应网站返回,shuju({'k1':'v1'});  也就相当于返回了一个带有参数的函数名称     function shuju(shj) {                               //自定义执行函数和响应网站返回的名称相同,参数就是响应网站返回的数据         for(var i in shj){                              //循环响应网站返回的数据             alert(i + ':' + shj[i]);                    //打印出数据的键和值,v1:k1         }     } </script>

响应页面

class fwdHandler(tornado.web.RequestHandler):     def get(self):                                      #接收get请求         # self.render("fwd.html")         self.write("shuju({'k1':'v1'});")               #返回的数据       def post(self):         self.write("post请求成功")

ajax的JSONP方式:

ajax跨域请求本质上就是上面自定义跨域的方式,只不过ajax帮我们封装好了,不用我们去创建script标签

请求页面(jquery):

<input type="button" value="跨域提交" onclick="doajax();"/> <script>     function doajax() {                                 //当点击提交按钮是执行函数         $.ajax({             type: 'GET',             url: 'http://www.fwd.com:8001/fwd',             dataType: 'jsonp',   //JSONP,数据类型             jsonpCallBack:'shj'  //接收响应页面带有参数的函数名称,shj来自响应端         });     }     //响应网站返回,shuju({'k1':'v1'});  也就相当于返回了一个带有参数的函数名称     function shuju(shj) {                               //自定义执行函数,和响应网站返回的名称相同,也就会执行自定义函数,而参数就是响应网站返回的数据         for (var i in shj) {                            //循环响应网站返回的数据             alert(i + ':' + shj[i]);                    //打印出数据的键和值         }     } </script>

响应端:

class fwdHandler(tornado.web.RequestHandler):     def get(self):                                      #接收get请求         # self.render("fwd.html")         self.write("shuju({'k1':'v1'});")               #返回数据     def post(self):         self.write("post请求成功")

法二、基于CORS实现跨域Ajax

请求页面不变,响应端返回数据的时候带有响应头标识,告诉浏览器允许跨域请求。

响应端:

class fwdHandler(tornado.web.RequestHandler):     def get(self):                                      #接收get请求         pass     def post(self):         self.set_header('Access-Control-Allow-Origin','*')         self.write("{'k1':'v1'}")  # 返回数据

跨域传输cookie(跨域请求中,默认HTTP Authentication信息,Cookie头以及用户的SSL证书都是不会被发送):

请求页面(jquery):

xhrFields:{withCredentials: true},          //传递Cookie头以及用户的SSL证书

响应端(python):

class fwdHandler(tornado.web.RequestHandler):     def get(self):                                      #接收get请求         pass     def options(self):                                                                        #接收预检的options请求         self.set_header('Access-Control-Allow-Credentials', "true")                           #传递Cookie头以及用户的SSL证书         self.set_header('Access-Control-Allow-Origin', 'http://www.khd.com:8002')             #预检请求或者数据请求时允许跨域,允许跨域的域名         self.set_header('Access-Control-Allow-Methods', 'PUT')                                #预检请求时允许请求页面的请求方式跨域,允许跨域的请求方式(多个逗号隔开)         self.set_header('Access-Control-Allow-Headers', "k1,k2")                              #预检请求时允许请求页面ajax设置请求头headers属性跨域,允许跨域的headers属性请求头(多个逗号隔开)     def put(self):         self.set_header('Access-Control-Allow-Credentials', "true")                           # 传递Cookie头以及用户的SSL证书         self.set_header('Access-Control-Allow-Origin','http://www.khd.com:8002')         self.write("{'k1':'v1'}")                       # 返回数据         self.set_cookie('kkkkk', 'vvvvv')               #写入cookie         print(self.get_cookie('kkkkk'))                 #获取cookie

本文发表于2017年11月04日 12:34
(c)注:本文转载自https://my.oschina.net/u/3688629/blog/1560497,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2149 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1