1、什么是跨域问题
在页面中使用js访问其他网站的数据时,就会出现跨域问题,比如在网站中使用ajax请求其他网站的天气、快递或者其他数据接口时,以及hybrid app中请求数据,浏览器会提 示一下错误:
XMLHttpRequest cannot load http://你请求的域名. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://当前页的域名' is therefore not allowed access.
2、为什么会出现跨域问题
因为浏览器收到同源策略的限制,当前域名的js只能读取同域下的窗口属性。
同源策略: 不同的域名, 不同端口, 不同的协议不允许共享资源的, 保障浏览器安全。
同源策略时针对浏览器设置的门槛。如果绕过浏览就能实现跨域,所以说早期的跨域都是打着安全路数的擦边球,都可以认为是 hack 处理。
3、现在总结一下解决跨域的几种方法
jsonp 跨域方法
我们提供一个 script 标签. 请求页面中的数据, 同时传入一个回调函数的名字. 服务器端得到名字后, 拼接函数执行格式的字符串. 发送回浏览器. script 在下载代码以后并执行, 执行的就是这个函数调用形式的字符串, 因此就将本地函数调用了.同时拿到了从服务器端得到的数据。
window.name
window对象的name属性是一个很特别的属性,当该window的location变化,然后重新加载,它的name属性可以依然保持不变。那么我们可以在页面A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给 window.name,iframe加载完成之后,页面A修改iframe的地址,将其变成同域的一个地址,然后就可以读出window.name的值了。这个方式非常适合单向的数据请求,而且协议简单、安全。不会像JSONP那样不做限制地执行外部脚本。
document.domain
通过修改document的domain属性,我们可以在域和子域或者不同的子域之间通信。同域策略认为域和子域隶属于不同的域,比如 www.a.com和sub.a.com是不同的域,这时,我们无法在www.a.com下的页面中调用sub.a.com中定义的JavaScript 方法。但是当我们把它们document的domain属性都修改为a.com,浏览器就会认为它们处于同一个域下,那么我们就可以互相调用对方的 method来通信了。
window.postMessage
window.postMessage是HTML5定义的一个很新的方法,这个方法可以很方便地跨window通信。由于它是一个很新的方法,所以在很旧和比较旧的浏览器中都无法使用。
借助于服务器代码来跨域(正向代理、反向代理)
正向代理: 我借助与我的服务器, 像数据服务器发送数据, 我的服务器只需要向数据服务器发送get请求即可
反向代理: 与正向代理类似, 但是不借助于脚本, 而是直接使用 服务器映射 url.
例如: 我们的 url 是 http://studyit.com
数据服务器的 url 是 http://api.botue.com/login
在 apache 配置一个 url 的代理映射
理论上使用 url: http://studyit.com/api 是在网站根目录下找 api 文件夹
但是现在 apache 提供一个映射的功能, 将 /api 映射到 http://api.botue.com
有了这个映射, 那么 访问 http://api.botue.com/login 就可以利用 /api/login来访问了.
反向代理的好处:
不仅实现了跨域( 服务器帮我们实现的 ), 而且访问数据的时候就好像在访问本地服务器一样.如此, 诸如 cookie 等数据就可以直接获得了.
怎么使用 反向代理( 不同的服务器的使用方法不一样 )
1) 找到 httpd.conf 配置文件, 找到里面的 porxy 开头的两个模块加载项. 去掉其注释.
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
2) 找到虚拟主机的配置文件. 需要谁来做反向代理 就修改谁的配置文件,在虚拟主机的设置中( 就是那一对尖括号中 )添加两个选项
ProxyRequests Off
ProxyPass /abc http://test2.com
3) 重启服务器
CORS 跨域
CORS 是在 es5 之后提出的跨域方案. 只需要在服务器配置一个跨域响应头接口
与jsonp相比的优点:
1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。
代码如下:
客户端:
<!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> <button id="btn">请求</button> <script src="./jquery-3.2.0.js"></script> <script> $( '#btn' ).click(function () { $.ajax( { url: 'http://test2.com/03-index.php', success: function ( info ) { console.log( info ); } }); }); </script> </body> </html>
服务器端:
<?php // header( 'Access-Control-Allow-Origin: *' ); // 允许任意的网站跨域 header( 'Access-Control-Allow-Origin: http://test1.com' );//允许指定网站 echo 'cors 跨域'; ?>
以上这篇完美解决浏览器跨域的几种方法(汇总)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小牛知识库。
本文向大家介绍Ajax跨域的完美解决方案,包括了Ajax跨域的完美解决方案的使用技巧和注意事项,需要的朋友参考一下 公司要做一个活动页面,在其过程中发现所有的接口,ajax请求跨域。这里对跨域做个简单介绍以及提供几种解决办法。 由于浏览器实现的同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,所以AJAX是不允许跨域的。这里提供自己常用的三种方法: 1、j
本文向大家介绍C#浏览器提示跨域问题解决方案,包括了C#浏览器提示跨域问题解决方案的使用技巧和注意事项,需要的朋友参考一下 一,我们使用两个域名互相访问的时候会提示跨域,原因在哪里呢?如下图跨域,我们探究下 是什么原因导致浏览器报这个错呢? 二,我们研究下看看请求是否成功。,如下图,浏览器返回的是200,证明请求是成功了,同时返回是成功了,那为什么还提示跨域呢? 三,经过看浏览器跨域的提示可知道“
本文向大家介绍详解Javascript几种跨域方式总结,包括了详解Javascript几种跨域方式总结的使用技巧和注意事项,需要的朋友参考一下 在客户端编程语言中如javascript,同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。只有当两个域具有相同的协议,相同的主机,相同的端口时,我们就认定他们是相同的域。可是在实际开发中我们经常需要获取其他域的
本文向大家介绍vue跨域解决方法,包括了vue跨域解决方法的使用技巧和注意事项,需要的朋友参考一下 vue项目中,前端与后台进行数据请求或者提交的时候,如果后台没有设置跨域,前端本地调试代码的时候就会报“No 'Access-Control-Allow-Origin' header is present on the requested resource.” 这种跨域错误。 要想本地正常的调试,解
本文向大家介绍js清除浏览器缓存的几种方法,包括了js清除浏览器缓存的几种方法的使用技巧和注意事项,需要的朋友参考一下 关于浏览器缓存 浏览器缓存,有时候我们需要他,因为他可以提高网站性能和浏览器速度,提高网站性能。但是有时候我们又不得不清除缓存,因为缓存可能误事,出现一些错误的数据。像股票类网站实时更新等,这样的网站是不要缓存的,像有的网站很少更新,有缓存还是比较好的。今天主要介绍清除缓存的几种
本文向大家介绍javascript跨域的方法汇总,包括了javascript跨域的方法汇总的使用技巧和注意事项,需要的朋友参考一下 此文章学习借鉴了一些其他前端同学的文章,自己做了个实践总结 以下的例子包含的文件均为为 http://www.a.com/a.html 、http://www.a.com/c.html 与 http://www.b.com/b.html,要做的都是从a.html获取b