jsonp跨域

Jquery jsonp跨域 实现天气预报

JSONP由来

要解释JSONP的来由,先要说一下浏览器的“同源策略(SOP:Same Origin Policy)”。 简而言之,就是浏览器限制脚本程序只能和同协议、同域名、同端口的脚本进行交互,这包括共享和传递变量等。cookie的传递也是遵从同样策略。这就造成一些涉及到多个服务器的应用在整合时一些麻烦。跨域访问的问题造成A站点的Ajax代码无法访问B站点的数据。
如何解决跨域访问呢?那就要借助浏览器的一个特性:尽管浏览器不允许页面中的脚本程序跨域 读取数据,但却允许HTML引用跨域的资源,如图片,CSS和脚本程序。对于脚本程序的引用比较特殊,它被浏览器解析以后,就和本地的脚本程序别无二致且可立即进行解释并执行。如在B站点的一个js文件,一个简单的提示框:alert(“This is Victor!”);。在A站点引用这个js,这个脚本就会在B站点的应用中执行,显示一个alert信息。由于站外脚本的引用是通过script tag来实现的,而脚本程序又可通过DOM的方式可以对HTML页面的所有标签进行控制(包括动态的创建script标签),这就可以实现通过调用站外程序对本地资源进行更改了。另外,通过script 标记的使用, 就可从服务端直接返回可执行的JavaScript函数调用或者JSON数据

JSONP原理与实现

首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 JSON数据。然后以JavaScript 语法的方式,生成一个function, function名字就是传递上来的参数jsonp.
然后,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段 js 语法的文档,返回给客户端。
最后,在客户端浏览器中解析script标签,并执行返回的JavaScript文档,此时数据作为参数,传入到了客户端预先定义好的回调函数里(动态执行回调函数) 。
其实 JSONP是个很简单的一个东西。主要是利用了 script标签对javascript文档的动态解析来实现。(其实也可以用eval函数)

jsonp 参数

jsonp 参数 在一个jsonp请求中重写回调函数的名字。这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,比如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

jsonpCallback 参数

为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。这主要用来让jQuery生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。

下面就是用jq里面封装的jsonp ,来尝试跨域请求,天气预报

HTML:


<h1>weather查询</h1>
    <div class="outer">
        <p>请输入city</p>
        <input type="text"  id="city-name-input">
        <span class="button" id="btn-search-city">查询</span>
        <span class="error">号码有误 或 无数据</span>
        <span id="label-result">
        </span>
	</div>

JS:

//search city
//param: cityCode <城市码>
 function searchCity(cityCode) {
 	// k780 的数据接口
 	var url = 'http://api.k780.com:88/?app=weather.today&weaid='+cityCode+'&appkey=15640&sign=4866dd3f2aadc62ab2f049cc35d2df15&format=json&jsoncallback=data';
 	$.ajax({
 		url: url,
 		dataType: "jsonp",
                jsonp: "callback",
                jsonpCallback: "data" ,
 		success: function(data) {
 			btn.removeClass('on-action');
			lb.html(data.result.citynm+'-'+data.result.days+'<br/>'+
				data.result.weather+'<br/>'+
				data.result.wind+'<br/>'+
				data.result.temperature+'<br/>'+
				data.result.wind+':'+data.result.winp+'<br/>'
				); 			
 		},
 		error:function(XMLHttpRequest, textStatus, errorThrown){
            alert(XMLHttpRequest.status);
            alert(XMLHttpRequest.readyState);
            alert(textStatus);
    } 
 	})
 	function data(datainfo){
 		console.log(datainfo);
 	}
 }

说明:

  1. 这里用的是K780的天气数据接口,所以在写url的时候要根据k780提供的来,包括后面的jsonCallback=data,他返回的数据是可以重写的,但是要在ajax里面注明jsonCallback=data,要一致
  2. 注意:jquey是不支持post方式跨域的。
  3. JSONP是一种脚本注入(Script Injection)行为,所以也有一定的安全隐患。 (跨站脚本攻击XSS?)
posted @ 2016-09-13 18:29  无夆  阅读(144)  评论(0编辑  收藏  举报