跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域
原因就是安全问题:如果一个网页可以随意地访问另外一个网站的资源,那么就有可能在客户完全不知情的情况下出现安全问题。比如下面的操作就有安全问题:
既然有安全问题,那为什么又要跨域呢? 有时公司内部有多个不同的子域,比如一个是location.company.com ,而应用是放在app.company.com , 这时想从 app.company.com去访问 location.company.com 的资源就属于跨域。
由于浏览器一般不对script,img等进行跨域限制,所以我们有机会通过script的方式来实现跨域访问。
跨域访问需要用到两样东东,一个是JSON,一种基于文本的传输协议;一种是JSONP,一群码农想出来的跨域解决方案。关于JSON与JSONP的解释,可以参考 JSON & JSONP
服务端要检查访问的请求参数,如果没有callback,则可以按照之前的流程走;如果带着callback参数,则需要将返回的结果包装在callback里面。
比如请求的URL是: app.company.com/location?callback=myCallback , 那么服务端则需要把结果封装进myCallback 函数里面, 如下
if (params.query && params.query.callback) { //console.log(params.query.callback); var str = params.query.callback '(' JSON.stringify(data) ')';//jsonp res.end(str); } else { res.end(JSON.stringify(data));//普通的json }
客户端有多种方式可以实现JSONP的调用:
$scope.jqueryJsonpRequest = function(){ jQuery.ajax({ type: 'get', async: false, url: 'https://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts', dataType: 'jsonp', jsonp: 'callback',//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:'flightHandler',//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写'?',jQuery会自动为你处理数据 success: function(json){ alert('success' JSON.stringify(json)); }, error: function(){ alert('fail'); } }); };
$http.jsonp('https://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK') .success(function(data){ alert('success:' data); }).error(function(err){ alert('error:' err); });
手动实现
不管是jQuery也好,AngularJS也罢,底下都不是发起XHR (XML HTTP Request),而都是通过加载javascript的方式来做的,所以如果项目没有依赖jQuery或者AngularJS,则可以自己手动实现jsonp的调用。
原理很简单,就是用javascript动态加载一个script文件,同时定义一个callback函数给script执行而已。
//定义callback 函数var myCallbackFunction = function(data){ // 对返回的数据做后续处理 alert('uuu:' JSON.stringify(data)); }//把callback函数赋给window对象,供script回调 window.myCallbackFunction = myCallbackFunction;//创建并加载scriptvar script = document.createElement('script');script.src = 'https://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=myCallbackFunction';document.body.appendChild(script);
联系客服