Home » Code » ajax跨域与jsonp

ajax跨域与jsonp

今天想在某页面加载完成时请求一个公共接口获得一些信息,谁知出现如下信息:

“XMLHttpRequest cannot load xxx……  No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin xxx…… is therefore not allowed”

没错,就是传说中的ajax跨域了。网上搜索都说什么加个header头,但试了不行,更多的说什么jsonp,并附上了jQuery代码,将dataType设置为”jsonp”,并添加一个jsonp参数写什么”callback”,还要在服务器端代码。我擦,一时给懵了,这公共的接口人家的我又不能动,这搞的什么飞机?感觉这些回答都没说到点子,什么是jsonp都没讲啊?再加搜索,终于搞清楚了一些。

请求自己服务器看看jQuery的jsonp是什么东西,代码如下:

$("#button").click(function(){
	$.ajax({
		url: "http://115.28.132.38/aa.php",
		dataType: "jsonp",
		jsonp: "callback",
		jsonpCallback: "a",
		success: function(data){
			console.log('sb');
		}
	})
})

服务器端代码:

<?php
$callback = $_GET['callback'];
sleep(5);
echo $callback.'('.json_encode(array('id'=>11)).')';

点击请求,可以看到其在html的head里边添加了一个script标签,数据请求完成后标签又删除了。

jsonp
由上面可以看到,ajax跟jsonp完全是两个不同的东西,ajax是XMLHttpRequest请求,jsonp只是添加一个script标签,请求是这个script标签发起的。ajax请求有所谓的同源策略,也就是说受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。而script标签发起的请求却没有这个限制,因此可用于跨域请求。

jsonp的基本原理,先在客户端写好一个回调函数,请求时将这个函数名传过去,服务器端返回的字符串就是运行这个回调函数的代码,参数是请求希望得到的json数据。跟iframe无刷新上传差不多的,关键点就是服务器返回的字符串就是能够运行这个回调函数!!!

用javascript简单模仿jQuery的jsonp方法如下:

var myJsonp = function(param){
	var script = document.createElement("script");
	var src = param.src + "?" + param.jsonp + "=" + param.jsonpCallback + "&_=" + new Date().getTime();
	script.src=src;
	script.onload = function(){
		document.head.removeChild(script);
	}
	document.head.appendChild(script);
}

function ss(data){
	console.log(data);
}

document.getElementById("button").addEventListener("click", function(){
	myJsonp({
		src: "http://115.28.132.38/aa.php", 
		jsonp: "callback", 
		jsonpCallback: "ss",
	})
}, false);

传入的src参数,就是script标签请求的地址。jsonp参数,表示以这个作为参数名将回调函数传给服务器,服务器通过它接收到回调函数的名称,也就是jsonpCallback参数的值。发送时?callback=ss,服务器接收$_GET[‘callback’],得到ss,返回ss({xx: xxx}),客户端运行ss函数,整个jsonp就这么个过程。

由上看到,jsonp这需要服务器配合,如果服务器不能接收$_GET[‘callback’],并返回$_GET[‘callback’].”({xxx: xxxx})”,压根没反应啊。如果一些公共接口提供jsonp的支持那当然没问题,不提供的话,压根没法子了。其实,可以用php啊,php请求没有不能跨域之说,ajax请求php,php直接file_get_contents()请求公共接口返回数据,这不就可以了嘛,中转一下即OK。

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.