目前主流的前端跨域请求方式有两种,一种是XHR2 CORS,也就是在服务端填上响应头:
header(“Access-Control-Allow-Origin:*”);
/星号表示所有的域都可以接受,/
header(“Access-Control-Allow-Methods:GET,POST”);
CORS不支持ie10以下。但是
第二种是更加方便的就是jsop了,jsop有很多种实现方式,除了原生的 js script jsop之外,其他支持jsop的框架也都能完成。我今天主要就是讲一讲自己在使用jquery jsop时碰到的坑以及jquery ajax和jquery jsop 的区别。
首先请看我的demo:
//ajax方法
function total_tendency() {
$.ajax({
url: "/count/storage/data?callback=storageSurvey",
dataType: "jsonp", //指定服务器返回的数据类型为jsonp
type: "GET",
async:true,
jsonp: "callback", ///指定参数名称,默认为callback
jsonpCallback:"storageSurvey", //指定回调函数名称
success: function (data) {
storageSurvey_local(data);
},
error:function () {
alert("error");
}
}
function storageSurvey_local(data) {
//将后台返回的数据先进行base64解码,再转换成json格式。
function decode(rtnData){
var dstr = kvcommon.base64Decode(rtnData);
var rtnData = kvcommon.Ajax.Str2Json(dstr);
return rtnData;
}
var now_data = decode(data);
var json = now_data[0];
console.log(now_data);
if(json.status == 0) {
var length = json.len;
modules = {};
//数据渲染
var modules = json.storage;
var max_count = json.max_count;
//在model_add()这个方法里进行数据获取和渲染
model_add(length,modules,max_count);
}
}
在total_tendency( )这个函数里的ajax中我使用的ajax里可以看到,所有加了注释的地方都是与普通ajax传json数据不一样的地方。
只有这些不同吗?当然不是的,网上很多都说ajax和jsop不能归结为一种东西,事实上也正是如此,为什么这么说?请看如下代码:
//ajax方法
function total_tendency() {
$.ajax({
url: "/count/storage/data?callback=storageSurvey",
dataType: "jsonp", //指定服务器返回的数据类型为jsonp
type: "GET",
async:true,
jsonp: "callback", ///指定参数名称,默认为callback
jsonpCallback:"storageSurvey", //指定回调函数名称
success: function (data) {
//把success里调用的函数改为回调函数名。
storageSurvey(data);
},
error:function () {
alert("error");
}
}
function storageSurvey(data) {
// 调用次数测试
alert("test");
//将后台返回的数据先进行base64解码,再转换成json格式。
function decode(rtnData){
var dstr = kvcommon.base64Decode(rtnData);
var rtnData = kvcommon.Ajax.Str2Json(dstr);
return rtnData;
}
var now_data = decode(data);
var json = now_data[0];
console.log(now_data);
if(json.status == 0) {
var length = json.len;
modules = {};
//数据渲染
var modules = json.storage;
var max_count = json.max_count;
//在model_add()这个方法里进行数据获取和渲染
model_add(length,modules,max_count);
}
}
再将ajax success中调用的函数名改为回调函数名后,在此函数中加入一个alert(“test”),执行后发现test弹出了两次。也就是说storageSurvey( )这个函数执行了两次。再看下面这这段代码:
//ajax方法
function total_tendency() {
$.ajax({
url: "/count/storage/data?callback=storageSurvey",
dataType: "jsonp", //指定服务器返回的数据类型为jsonp
type: "GET",
async:true,
jsonp: "callback", ///指定参数名称,默认为callback
jsonpCallback:"storageSurvey", //指定调用的回调函数名称
/* success: function (data) {
//把success里调用的函数改为回调函数名。
storageSurvey(data);
},
error:function () {
alert("error");
}*/
}
function storageSurvey(data) {
// 调用次数测试
alert("test");
//将后台返回的数据先进行base64解码,再转换成json格式。
function decode(rtnData){
var dstr = kvcommon.base64Decode(rtnData);
var rtnData = kvcommon.Ajax.Str2Json(dstr);
return rtnData;
}
var now_data = decode(data);
var json = now_data[0];
console.log(now_data);
if(json.status == 0) {
var length = json.len;
modules = {};
//数据渲染
var modules = json.storage;
var max_count = json.max_count;
//在model_add()这个方法里进行数据获取和渲染
model_add(length,modules,max_count);
}
}
将success和error屏蔽,执行代码,有意思的是test还会弹出来,不过只弹出来了一次,意味着storageSurvey( )这个函数这次只执行了一次。
看出jsop与ajax的区别了吗?如果是ajax,你把在success中调用的函数屏蔽掉,它还会执行吗?显然不会!那么在jsop中为什么会执行呢?原因就是这句话:
jsonpCallback:”storageSurvey”,
这句属性的设置。它本意是设置请求url中callback=后面那个回调函数的名称,但有意思的是,如果你在此ajax函数外的js中重写了这么一个函数,ajax就会直接调用此函数。jquery jsop的这个功能应该是基于原生的js调用jsop的方法,而原生js实现jsonp跨域也更能让大家理解jsonp实现跨域的原理。看下面这段代码:
<html>
<head>
head>
<body>
<script type="text/javascript">
function connect_data(data){
alert("age:" + data.age + "name:" + data.name);
}
script>
<script type="text/javascript" src="jquery-1.8.3.min.js">
script>
<script type="text/javascript" src="这里写服务器端调用此函数的文件路径">script>
body>
html>
然后只需在服务器端以connect_data( ) 命名的函数中返回json数据即可,如有需要,也可自行选择加密方式,就如我在一开始的demo中用的就是base64decode。
从上面的这个demo中可以看出,jsonp的跨域原理就是利用了src可以避开同源策略这一特性,在原生js中需要手动包裹一层script,在src里放请求路径,在路径里的文件中传输jsop数据。而jquery jsonp则自动动态的给你包裹了一层script标签和src属性。
补充: