跨域与JSONP

什么是跨域:

浏览器同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。
与一个不满足同源策略的域的页面进行交互,就是跨域。

跨域三种方案:

1. ifram标签

html中有一些标签不受同源策略限制,ifram就是其中一个。

2. postMessage

属于h5新增api。

3. JSONP

最常用的就是JSONP,也是面试中最常考的。JSONP简单来说就是动态生成js脚本。这里需要服务端配合,调用者可以传一个参数过去告诉服务端 “我想要一段调用XXX函数的js代码,请你返回给我”,于是服务器就可以按照客户端的需求来生成js脚本并响应了。
示例代码:

    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 

最终服务器端生成的返回给请求页面的代码段应该是这样的:

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

jsonp乍看给ajax很像,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装。
jquery实现jsonp:

    jQuery(document).ready(function(){ 
        $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
             jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
             success: function(json){
                 alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
             },
             error: function(){
                 alert('fail');
             }
         });
     });

但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加。

JSONP常考面试题:

手写jsonp:

var jsonp = function(url,param,callback){
    //处理url地址,查找?,如果没有?这个变量就有一个"?",有?这个变量接收一个&
    var querystring = url.indexOf("?") == -1?"?":"&";

    //处理参数{xx:xx}
    for(var k in param) {
        querystring += k + "=" + param[k] + '&';//?k=para[k]
    }

    //处理回调函数名
    var random = Math.random().toString().replace(".","");
    var cbval = "my_jsonp" + random;
    var cb = "callback="+cbval;

    querystring += cb;

    var script = document.createElement("script");
    script.src = url + querystring;

    //挂载回调函数
    window[cbval] = function(data) {
        //这里执行回调的操作,用回调来处理参数
      callback(data);
      //拿到了就删掉这个script
      document.body.removeChild(script);
    };

    document.body.appendChild(script);
}

jsonp(
    "https://www.baidu.com",
    {aa:11},
    function(){
        console.log(param);
    }
);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • JavaScript是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的...
    西瓜w阅读 1,776评论 0 1
  • 0. 前言 说到AJAX就会不可避免的面临两个问题。 AJAX以何种格式来交换数据? 第二个是跨域的需求如何解决?...
    公子七阅读 23,637评论 7 67
  • 1. 什么是同源策略 浏览器限制不同源的两个网站间脚本和文本的相互访问,只允许访问同源下的内容。所谓同源,就是指两...
    熊蛋子17阅读 697评论 1 6
  • 一:什么是同源策略 同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。 同源:URL由协议、域名、端口和路径...
    南方小小姑娘阅读 770评论 0 1
  • 今天第33个教师节暨表彰大会,要求7:20到会,结果弄着弄着就晚了,结果整得路上狂飙到100多,虽然知道也不会太晚...
    筱薇_旭东阅读 391评论 0 0