借助<script>发送HTTP请求:JSONP

一、认识JSONP

<script>元素可以作为一种Ajax传输机制:只须设置<script>元素的src属性(假如它还没插入到document中,需要插入进去),然后浏览器就会发送HTTP请求下载src属性所指向的URL。使用<script>元素进行Ajax传输的一个主要原因是,它不受同源策略的影响,因此可以使用它们从其他的服务器请求数据,第二个原因是包含JSON编码数据的响应体会解码。 这种使用<script>元素作为Ajax传输的技术称为JSONP。
假设你已经写了一个服务,它处理GET请求并返回JSON编码的数据,同源文档可以在代码中使用XMLHttpRequest和JSON.parse()。假如在服务器上启用了CORS,在新的浏览器下,跨域的文档也可以使用XMLHttpRequest享受到该服务。在不支持CORS的旧浏览器下,跨域文档只通过<script>元素访问这个服务。使用JSONP,JSON响应数据是合法的JavaScript代码,当它到达浏览器将执行它。

二、原理分析

同源策略下,某个服务器是无法获取到服务器以外的数据,但是html里面的img,iframe和script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。而JSONP 就是通过script节点src调用跨域的请求。
当我们向服务器提交一个JSONP的请求时,我们给服务传了一个特殊的参数,告诉服务端要对结果特殊处理一下。这样服务端返回的数据就会进行一点包装,客户端就可以处理。
例如。服务端和客户端约定要传一个名为callback的参数来使用JSONP功能,比如请求的参数如下:

http://www.example.net/sample.aspx?callback=mycallback

如果没有后面的callback参数,即不使用JSONP的模式,该服务的返回结果可能是一个单纯的json字符串,比如:{foo:'bar'}。但是如果使用JSONP模式,那么返回的是一个函数调用:mycallback({foo:'bar'}),这样我们在代码之中,定义一个名为mycallback的回调函数,就可以解决跨域问题了。

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script> 
<title></title> 
<style> 
body {
    background-color: #f3f3f3;
}
.main {
    width: 645px;
    margin: 30px auto;
    position: relative;
}
form {
    font-size: 0;
}
#result {
    position: absolute;
    top: 41px;
    left: -1px;
    width: 537px;
    border: 1px solid #e3e3e3;
    border-top: 0 none;
    background-color: #fff;
    padding: 0;
    color: #333;
    margin: 0;
    list-style: none;
}
#result li {
    line-height: 24px;
    padding-left: 12px;
}
#keyWords {
    width: 480px;
    padding: 10px 50px 10px 7px;
    border: 0;
    background-image: none;
    height: 20px;
    line-height: 20px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    vertical-align: middle;
    outline:none;
} 
#search {
    width: 104px;
    height: 40px;
    line-height: 40px;
    line-height: 37px\9;
    padding: 0;
    border: 0;
    background-position: -464px -42px;
    cursor: pointer;
    color: #000;
    font-size: 16px;
    vertical-align: middle;
    outline:none;
} 
#search:hover {
    box-shadow: 1px 1px 3px rgba(0,0,0,0.2);
}
</style> 
<script type="text/javascript"> 
function relatedWords(data){ 
    var _html=[]; 

    for(var i=0;i<data.s.length;i++){
        _html.push('<li>' + data.s[i] + '</li>');
    }

    $('#result').html(_html.join(''));
}; 

$(function(){ 
    $('#keyWords').keyup(function() { 
        var val = $(this).val(); 
        if (val.trim() == '') {
            return ;
        }

        $.ajax({ 
            url:'http://suggestion.baidu.com/su?wd='+val+'&json=1&p=3&req=2&cb=relatedWords', 
            dataType:'jsonp' 
        });
    }); 
}); 
</script> 
</head> 
<body> 
<div class="main">
    <form>
        <input type="text" id="keyWords" />
        <input type="button" id="search" value="百度一下" />
    </form>
    <ul id="result"></ul>
</div>


</body> 
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,933评论 18 139
  • JSONP(JSON with Padding)是一种JSON扩展,用来解决由浏览器同源策略引起跨域限制。跨域限制...
    留七七阅读 2,511评论 0 4
  • AJAX 原生js操作ajax 1.创建XMLHttpRequest对象 var xhr = new XMLHtt...
    碧玉含香阅读 3,274评论 0 7
  • 我喜欢我自己 我喜欢我自己的大眼睛 浓黑的眉毛,白皙的皮肤均匀的身段 喜欢自己有一颗善良的心,尊老爱幼的品德,喜欢...
    燕子_767e阅读 148评论 0 0
  • you3690阅读 58评论 0 0