JSONP原理及简单实现 可做简单插件使用
JSONP实现跨域通信的解决方案。
在jquery中,我们可以通过$.ajax的dataType设置为jsonp来调用jsonp,但是jsonp和ajax的实现原理一个关系都木有。jsonp主要是通过script可以链接远程url来实现跨域请求的。如:
<script src="http://jsonp.js?callback=xxx"></script>
callback定义了一个函数名,而远程服务端通过调用指定的函数并传入参数来实现传递参数。
搜索了网上好多文章,他们实现方法都过于简单,要实际应用还要多加修改,我在这里封装了一个对象,可以直接运用于实际操作。
var JSONP = {
// 获取当前时间戳
now: function() {
return (new Date()).getTime();
},
// 获取16位随机数
rand: function() {
return Math.random().toString().substr(2);
},
// 删除节点元素
removeElem: function(elem) {
var parent = elem.parentNode;
if(parent && parent.nodeType !== 11) {
parent.removeChild(elem);
}
},
// url组装
parseData: function(data) {
var ret = "";
if(typeof data === "string") {
ret = data;
}
else if(typeof data === "object") {
for(var key in data) {
ret += "&" + key + "=" + encodeURIComponent(data[key]);
}
}
// 加个时间戳,防止缓存
ret += "&_time=" + this.now();
ret = ret.substr(1);
return ret;
},
getJSON: function(url, data, func) {
// 函数名称
var name;
// 拼装url
url = url + (url.indexOf("?") === -1 ? "?" : "&") + this.parseData(data);
// 检测callback的函数名是否已经定义
var match = /callback=(\w+)/.exec(url);
if(match && match[1]) {
name = match[1];
} else {
// 如果未定义函数名的话随机成一个函数名
// 随机生成的函数名通过时间戳拼16位随机数的方式,重名的概率基本为0
// 如:jsonp_1355750852040_8260732076596469
name = "jsonp_" + this.now() + '_' + this.rand();
// 把callback中的?替换成函数名
url = url.replace("callback=?", "callback="+name);
// 处理?被encode的情况
url = url.replace("callback=%3F", "callback="+name);
}
// 创建一个script元素
var script = document.createElement("script");
script.type = "text/javascript";
// 设置要远程的url
script.src = url;
// 设置id,为了后面可以删除这个元素
script.id = "id_" + name;
// 把传进来的函数重新组装,并把它设置为全局函数,远程就是调用这个函数
window[name] = function(json) {
// 执行这个函数后,要销毁这个函数
window[name] = undefined;
// 获取这个script的元素
var elem = document.getElementById("id_" + name);
// 删除head里面插入的script,这三步都是为了不影响污染整个DOM啊
JSONP.removeElem(elem);
// 执行传入的的函数
func(json);
};
// 在head里面插入script元素
var head = document.getElementsByTagName("head");
if(head && head[0]) {
head[0].appendChild(script);
}
}
};
实现过程基本写在注释里啦,自己看。调用的方法跟jQuery基本一样。如:
var data = {
from: "北京",
count: 27,
output: "json",
callback: "?"
}
JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp", data, function(json) {console.log(json)});
当然要这么写也行:
JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp?from=北京&count=27&output=json&callback=?", null, function(json) {console.log(json)});
至于服务端的实现,那就比较简单了,以php为例:
$callback = !empty($_GET['callback']) ? $_GET['callback'] : 'callback';
echo $callback.'( .json_encode( $data ).')';
JSONP原理及简单实现 可做简单插件使用的更多相关文章
- Asp.net MVC 简单分页 自做简单分页
Asp.net MVC 简单分页: public static string Pager(int page,int pageSize,int total) { ...
- 简单透彻理解JSONP原理及使用
首先提一下JSON这个概念,JSON是一种轻量级的数据传输格式,被广泛应用于当前Web应用中.JSON格式数据的编码和解析基本在所有主流语言中都被实现,所以现在大部分前后端分离的架构都以JSON格式进 ...
- 利用php的序列化和反序列化来做简单的数据本地存储
利用php的序列化和反序列化来做简单的数据本地存储 如下程序可以做为一个工具类 /** * 利用php的序列化和反序列化来做简单的数据本地存储 */ class objectdb { private ...
- 阿里云api调用做简单的cmdb
阿里云api调用做简单的cmdb 1 步骤 事实上就是调用阿里api.获取可用区,比方cn-hangzhou啊等等.然后在每一个区调用api 取ecs的状态信息,最好写到一个excel里面去.方便排序 ...
- Java用户输入数值,做简单的猜数字游戏,导入基础的工具包util
Java用户输入数值,做简单的猜数字游戏,导入基础的工具包util,导入包的方法为,import java.util.*: 完整的实例代码: /* 导入基础工具包 */ import java.uti ...
- 简单使用limma做差异分析
简单使用limma做差异分析 Posted: 五月 12, 2017 Under: Transcriptomics By Kai no Comments 首先需要说明的是,limma是一个非常全 ...
- 简单使用DESeq做差异分析
简单使用DESeq做差异分析 Posted: 五月 06, 2017 Under: Transcriptomics By Kai no Comments DESeq这个R包主要针对count d ...
- 使用jmeter做简单的场景设计
使用jmeter做简单的场景设计 Jmeter: Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试.我之所以选择它,最重要的一点就是----开源 个人 ...
- Mycat 做简单的读写分离(转载)
大漠小狼的个人空间 http://www.51testing.com/html/34/369434-3686088.html 使用Mycat 做简单的读写分离(一) 原本使用的是amoeba做的读 ...
随机推荐
- Xcode迁移工程常见问题
[Xcode迁移工程常见问题] 1.Header Search Paths (HEADER_SEARCH_PATHS) 是否设置正确.在Search Paths group下. 2.Framework ...
- 08-Location总结图解
URI解析 首先要判断有没有精准匹配,能不能精准匹配.计算机里面没有什么这种差不多这种东西.跟人聊天才说差不多,最近过得怎么样啊,还行吧,差不多吧,这个不多是多还是不多啊. 预定义库->Gen ...
- QPS、PV和需要部署机器数量计算公式
QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准. TPS是 Transactions ...
- 19-字符串匹配(kmp || substr,find)
链接:https://www.nowcoder.com/acm/contest/77/C来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...
- Ubuntu16.04 ARM平台移植libcurl curl-7.63.0
libcurl是免费的轻量级的客户端网络库,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS,POP3, P ...
- oracle获取表和列的备注
using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Runti ...
- indexOf(String.indexOf 方法)
字符串的IndexOf()方法搜索在该字符串上是否出现了作为参数传递的字符串,如果找到字符串,则返回字符的起始位置 (0表示第一个字符,1表示第二个字符依此类推)如果说没有找到则返回 -1 返回 St ...
- js 判断今天是否上班
<script> var weekdate= getWeekDate() switch(weekdate){ case "星期一":; case "星期二&q ...
- C#ThreadPool学习
一.简介 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器 注意:线程池中启动的线程都是后台线程 二.主要方法 GetAvailableThread ...
- 接上一篇,Springcloud使用feignclient远程调用服务404 ,为什么去掉context-path后,就能够调通
一.问题回顾 如果application.properties文件中配置了 #项目路径 server.servlet.context-path=/pear-cache-service 则feigncl ...