前端跨域访问 曾经终败给现在 2022-06-14 01:44 205阅读 0赞 **一、同源策略** 做过开发的都知道,从A网站通过Ajax来请求另外一个B网站的特定内容,是很常见的需求,但是出于安全的考虑,浏览器是不允许你这样做的,这就是浏览器的同源策略; **何谓同源:** URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。 ** 同源策略:** 同源策略是Web层面上众多安全策略的一个,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。同源策略规定:不同域的客户端脚本在没明确授权的情况下,不能读写对方的资源。同域要求两个站点同协议、同域名、同端口, 表 1-1 展示了表中所列站点与http://www.foo.com是否同源的情况。 <table> <tbody> <tr> <td> <p> </p> <p>站<span style="font-family:Calibri"> </span><span style="font-family:宋体">点</span></p> </td> <td> <p>是否同源</p> </td> <td> <p>原<span style="font-family:Calibri"> </span><span style="font-family:宋体">因</span></p> </td> </tr> <tr> <td> <p>https://www.foo.com</p> </td> <td> <p>不同源</p> </td> <td> <p>协议不同,<span style="font-family:Calibri">https</span><span style="font-family:宋体">与</span><span style="font-family:Calibri">http</span><span style="font-family:宋体">是不同的协议</span></p> </td> </tr> <tr> <td> <p>http://xeyeteam.foo.com</p> </td> <td> <p>不同源</p> </td> <td> <p>域名不同,<span style="font-family:Calibri">xeyeteam</span><span style="font-family:宋体">子域与</span><span style="font-family:Calibri">www</span><span style="font-family:宋体">子域不同</span></p> </td> </tr> <tr> <td> <p>http://foo.com</p> </td> <td> <p>不同源</p> </td> <td> <p>域名不同,顶级域与<span style="font-family:Calibri">www</span><span style="font-family:宋体">子域不是一个概念</span></p> </td> </tr> <tr> <td> <p>http://www.foo.com:8080</p> </td> <td> <p>不同源</p> </td> <td> <p>端口不同,<span style="font-family:Calibri">8080</span><span style="font-family:宋体">与默认的</span><span style="font-family:Calibri">80</span><span style="font-family:宋体">端口不同</span></p> </td> </tr> <tr> <td> <p>http://www.foo.com/a/</p> </td> <td> <p>同源</p> </td> <td> <p>满足同协议、同域名、同端口,只是这里多了一个目录而已</p> </td> </tr> </tbody> </table> 同源策略主要限制了通过XMLHttpRequest实现的Ajax请求,如果请求的是一个“异源”地址,浏览器将不允许读取返回的内容,但是HTML还具有其它一些具有src属性的标签(比如<script>、<img>、<iframe>和<link>等),它们均具有跨域加载资源的能力,所以同源策略对它们不做限制。对于这些具有src属性的HTML标签来说,标签的每次加载都意味着针对目标地址的一次HTTP-GET请求。 ** ** **二、使用jsonp进行跨域** JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。JSONP也叫填充式JSON,是应用JSON的一种新方法,只不过是被包含在函数调用中的JSON。它是通过向其它域传入一个callback参数,通过其他域的后台将callback参数值和json串包装成javascript函数返回,因为是通过script标签发出的请求,浏览器会将返回来的字符串按照javascript进行解析执行,实现了域与域之间的数据传输。 JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。 callback(\{"name","trigkit4"\}); js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。 <script type="text/javascript"> function dosomething(jsondata)\{ //处理获得的json数据 \}</script><script src="http://example.com/data.php?callback=dosomething"></script> 使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了。 <script type="text/javascript"> $.getJSON('http://example.com/data.php?callback=?,function(jsondata)')\{ //处理获得的json数据 \});</script> jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。 ** ** **三、Jsonp和ajax对比** Ajax请求是通过XMLHttpRequest对象实现的; Jsonp是通过动态创建script标签就可以加载其它域的js文件,然后通过本页面就可以调用加载后js文件的函数。 ### ** ** ### ### **四、JSONP的优缺点** ### JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。 JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。 ** ** **五、其他跨域访问的方法** 1、通过修改document.domain来跨子域 2、使用iframe标签进行kuayu 3、使用window.name来进行跨域 4、使用HTML5中新引进的window.postMessage方法来跨域传送数据 5、服务器上设置代理页面
还没有评论,来说两句吧...