作为前端人员经常需要调用接口向服务器端请求数据,但有时并没有得到我们预期所想要的数据,而是报错了,出现了Access-control-Allow-Origin
的报错信息,则表明出现了跨域情况,在解决跨域问题之前,先要了解为什么会跨域。
同源策略
同源是指,域名,协议,端口相同。所谓“同源策略“,简单的说就是基于安全考虑,当前域不能访问其他域的东西。所以会产生跨域问题
在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的。否则会产生如下情况
但<img>
的src(获取图片),<script>
的src(获取javascript)都不符合同源策略,它们可以跨域获取数据。这里要介绍的JSONP就是利用<script>
的src来实现跨域获取数据的。
JSONP
JSONP实现跨域请求的原理简单的说,就是动态创建<script>
标签,然后利用<script>
的src 不受同源策略约束来跨域获取数据。就是
1 <script type="text/javascript"> 2 //返回的JSON作为参数传入回调函数中,通过回调函数来操作数据 3 function handleResponse(response){ 4 console.log(response); 5 } 6 7 window.onload = function() { 8 var oBtn = document.getElementById('btn'); 9 oBtn.onclick = function() { 10 //动态创建<script>标签,设置其src,回调函数在src中设置 11 var script = document.createElement("script"); 12 script.src = "https://xxx&callback=handleResponse"; 13 document.body.insertBefore(script, document.body.firstChild); 14 }; 15 } 16 </script>
1.JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都 可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
2.JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;
3.JSONP的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了。
jQuery封装JSONP
$.ajax({ url : "https://xxx", type : "GET", dataType : "jsonp", // 返回的数据类型,设置为JSONP方式 success: function(res){ console.log(res); } });
$.getJSON()
利用getJSON来实现,只要在地址中加上callback=?参数即可,参考代码如下:
$.getJSON("https://xxx&callback=?", function(data){ console.log(data); });
CORS
CORS全称Cross-Origin Resource Sharing(跨域资源共享),是HTML5规范定义的如何跨域访问资源。
Origin表示本域,也就是浏览器当前页面的域。当JavaScript向外域(如sina.com)发起请求后,浏览器收到响应后,首先检查Access-Control-Allow-Origin是否包含本域,如果是,则此次跨域请求成功,如果不是,则请求失败,JavaScript将无法获取到响应的任何数据。
假设本域是my.com
,外域是sina.com
,只要响应头Access-Control-Allow-Origin
为http://my.com
,或者是*
,本次请求就可以成功。
CORS的整个过程都由浏览器自动完成,前端无需做任何设置,跟平时发送ajax请求并无差异。so,实现CORS的关键在于服务器,只要服务器设置一个正确的Access-Control-Allow-Origin
,就可以实现跨域通信。
请求类型:
CORS分为简单请求和非简单请求(需预检请求)两类
符合如下的为简单请求,反之为非简单请求
请求方式使用下列方法之一: GET HEAD POST Content-Type 的值仅限于下列三者之一: text/plain multipart/form-data application/x-www-form-urlencoded
实例代码,以node.js为例
var express = require('express'); var app = express(); var allowCrossDomain = function (req, res, next) res.header('Access-Control-Allow-Origin', 'http://localhost:3001');//该字段表明可供哪个源跨域 } app.use(allowCrossDomain);
总的来说,使用CORS简单请求,对于前端来说无需做任何配置,与发送普通ajax请求无异,CORS的配置,完全在后端设置,配置起来也比较容易,相较于JSONP跨域只能使用get请求来说,也更加的便于我们使用。