一、跨域概念
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
同源是指,域名,协议,端口均相同
http://www.123.com/index.html 调用 http://www.123.com/server.PHP(非跨域)
http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)
http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)
请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
二、解决办法
1、JSONP
采用JSONP跨域Get 请求是一种常用的方案。但是该方式只支持GET请求。
那么什么是JSONP呢,它和JSON又有什么不同呢?以下是百度百科上的解释。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于 JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(网络传输速度快)。
JSONP(JSON with Padding)是JSON的 一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的。 元素是一个例外。利用 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
所以,JSONP是一种使用JSON数据的方式,返回的不是JSON对象,是包含JSON对象的javaScript脚本。Web页面上调用js文件时不受是否跨域的影响,而且拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>。所以,在进行跨域请求时, 通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,就直接使用JSON传递 javascript对象。即在跨域的服务端生成JSON数据,然后包装成script脚本回传,从而突破同源策略的限制,解了跨域访问的问题。
采用这种方式的问题是不支持POST请求;另外,JSONP不提供错误处理。如果动态插入的代码正常运行,你可以得到返回,但是如果失败了,那么什么都不会发生。
2、代理
例如www.123.com/index.html需要调用www.456.com/server.php,可以写一个接口www.123.com/server.php,由这个接口在后端去调用www.456.com/server.php并拿到返回值,然后再返回给index.html,这就是一个代理的模式。相当于绕过了浏览器端,自然就不存在跨域问题。
3、PHP端修改header(XHR2方式)
在php接口脚本中加入以下两句即可:
header('Access-Control-Allow-Origin:*');//允许所有来源访问
header('Access-Control-Allow-Method:POST,GET');//允许访问的方式