JSONP 正在参加 2021 年度 OSC 中国开源项目评选,请投票支持!
JSONP 在 2021 年度 OSC 中国开源项目评选 中已获得 {{ projectVoteCount }} 票,请投票支持!
2021 年度 OSC 中国开源项目评选 正在火热进行中,快来投票支持你喜欢的开源项目!
2021 年度 OSC 中国开源项目评选 >>> 中场回顾
JSONP 获得 2021 年度 OSC 中国开源项目评选「最佳人气项目」 !
授权协议 MIT
开发语言 JavaScript
操作系统 跨平台
软件类型 开源软件
开源组织
地区 不详
投 递 者 不详
适用人群 未知
收录时间 2009-01-20

软件简介

JSONP (JSON with Padding) 是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域获取资料。另一个解决这个问题的新方法是跨来源资源共享。

浏览器安全模型规定,XMLHttpRequest、框架(frame)等只能在一个域中通信。从安全角度考虑,这个规定很合理;但是,也确实给分布式(面向服务、混搭等等本周提到的概念)Web开发带来了麻烦。

为了实现跨域通信,通常的解决方案有3种:

本地代理:
需要一些硬件设施(没有服务器的客户端无法运行),并且带宽和潜伏时间也要加倍(远程服务器-代理服务器-客户端)。

Flash:
远程主机中需要部署一个crossdomain.xml文件,而且,Flash作为一门专有技术,其前途尚不明朗;换句话说,开发人员很可能要学习一种目标不确定的编程语言。

Script标签:
无法确切知道内容是否有效,没有标准的实现方法,又可能被认为是一种“安全风险”。

 


在此,我建议使用一种新技术,也是一种独立于标准的方法,即通过script标签来跨域获取数据,名为JSON with Padding,或者就叫JSONP。JSONP的原理很简单,但需要服务器端给予相应配合。大致来说,JSONP的实现思路就是在客户端编程时作好使用JSON数据的准备,然后再通过圆括号将这些数据括起来以创建一条有效的JavaScript语句(可能是一次有效的函数调用)。

也就是说,客户端可以使用一个用于命名jsonp的查询参数来决定可以获取的数据。最简单的情况下,如果jsonp参数为空,则返回的数据就是被括在圆括号中的JSON。

下面,我们就以del.icio.us的JSON API为例,来说明JSONP的原理。该API有一个“script tag”变量(即,可以将下面的URL作为script标签的src属性值,用以加载del.icio.us这个API提供的数据。——译者注)如下所示:

http://del.icio.us/feeds/json/bob/mochikit+interpreter:

  1. if(typeof(Delicious) == 'undefined') Delicious = {};
  2. Delicious.posts = [{
  3. "u": "http://mochikit.com/examples/interpreter/index.html",
  4. "d": "Interpreter - JavaScript Interactive Interpreter",
  5. "t": [
  6. "mochikit","webdev","tool","tools",
  7. "javascript","interactive","interpreter","repl"
  8. ]
  9. }]

如果用JSONP的方式来表示,那么与此具有相同语义的URL应该是这样的:

http://del.icio.us/feeds/json/bob/mochikit+interpreter?
jsonp=if(typeof(Delicious)%3D%3D%27undefined%27)
Delicious%3D%7B%7D%3BDelicious.posts%3D

单纯看这个URL似乎没有什么,但我们可以要求服务器在数据有效时给出通知。因此,我可以编写一个用于跟踪数据的小系统:

  1. var delicious_callbacks = {};
  2. function getDelicious(callback, url) {
  3. var uid = (new Date()).getTime();
  4. delicious_callbacks[uid] = function () {
  5. delete delicious_callbacks[uid];
  6. callback();
  7. };
  8. url += "?jsonp=" + encodeURIComponent("delicious_callbacks[" + uid + "]");
  9. // 手工输入代码,向文档中插入script标签
  10. };
  11.  
  12. getDelicious(doSomething, "http://del.icio.us/feeds/json/bob/mochikit+interpreter");

根据以上假设,用于获取数据的URL应该如下所示:
http://del.icio.us/feeds/json/bob/mochikit+interpreter?jsonp=delicious_callbacks%5B12345%5D

  1. delicious_callbacks[12345]([{
  2. "u": "http://mochikit.com/examples/interpreter/index.html",
  3. "d": "Interpreter - JavaScript Interactive Interpreter",
  4. "t": [
  5. "mochikit","webdev","tool","tools",
  6. "javascript","interactive","interpreter","repl"
  7. ]
  8. }])

可见,由于使用圆括号括住了返回的数据,这就相当于把一个JSONP请求转化成了一次函数调用,或者得到了一个纯粹的JSON直接量。服务器所要配合做的,就是在JSON数据的开头添加一小段文本(即回调函数的名称。——译者注)并将JSON数据放在括号中!

当然,接下来最好是使用Mochikit、Dojo等框架来抽象JSONP,从而让自己省去动手编写DOM以插入script标签的麻烦。

没错,JSONP只是解决了标准化的问题。假如远程主机想通过script标签向页面中注入恶意代码,而不是返回JSON数据,那么页面安全可能会 随时受到威胁。不过,一旦实现了JSONP,那么对开发人员来说肯定是一件省时省力的大好事,在此基础上各种一般化的抽象、教程及文档也会应运而生的。

展开阅读全文

代码

的 Gitee 指数为
超过 的项目

评论 (1)

加载中
更多评论
暂无内容
发表了博客
2013/03/13 21:59

JSONP

维基百科,自由的百科全书 JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。另一个解决这个问题的新方法是跨来源资源共享。 由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com 的服务器沟通,而 HTML 的 <script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 ...

0
0
发表于大前端专区
2014/04/21 15:55

JSONP

Use XMLHttpRequest when your HTML and JavaScript are hosted on the same machine as your data. Use JSONP when you need to access data hosted by a web service on a remote server (assuming that web service supports JSONP). A web service is a web API that is accessed by HTTP. ƒƒJSONP is a method of retrieving data by using the <script> element. ƒƒJSONP is JSON data wrapped in JavaScript; typic...

0
0
发表于大前端专区
2015/08/25 17:20

jsonp

jsonp

0
0
发表了博客
2020/10/08 16:32

jsonp

```js const jsonp = ({url, params, callbackName}) => { const generateUrl = () => { let dataStr = `` for (let key in params) { dataStr += `${key}=${params[key]}&` } dataStr += `callbackName=${callbackName}` return `${url}?${dataStr}` } return new Promise((resolve, reject) => { const scriptEle = document.createElement('script') scriptEle.src = generateUrl() document.body.appendChild(scriptEle) wi...

0
0
没有更多内容
加载失败,请刷新页面
点击加载更多
加载中
下一页
发表于AI & 大数据专区
2019/04/18 17:30

ajax使用jsonp跨域问题Cross-Origin Read Blocking (CORB) blocked cross-origin response

$(function(){      $.ajax({     type:"get",     url:"http://web.juhe.cn:8080/environment/water/river?river=黄河流域&key=c54b05e9318a3c33e4c618710978c41c",     dataType:"jsonp",     success:function(data){    console.log("data:"+data);    $("#info").html(data);     },     error:function(){       $("#info").html("AJAX请求失败");     },     beforeSend:function(){       $("#info").html("正在请求数据中......

8
0
2019/10/12 13:16

WdatePicker时间插件的iframe弹框跨域问题

一个8083的服务,加载了8082的页面,在8083和8082的页面用document.domain=‘localhost'解决了跨域问题,但是,在8082的页面上的所有时间插件弹框失败: 下面是问题代码,F是一个DIV,D是F中的iframe的document对象,所有console.log输出都是localhost,不明白为什么D.write跨域了,报错Uncaught DOMException: Failed to execute 'write' on 'Document': Can only call write() on same-origin documents.:...

1
0
发表了问答
2017/12/18 11:25

前后端分离跨域问题

公司第一次采用前后端来进行后台开发,在开发过程中出现了跨域问题,被折磨的快要疯了,是这样,后台登录完成后将用户信息保存在session中,再调另一个接口获取session中的用户信息,大概是因为跨域导致session丢失,然后经过一番百度,使用springsession+redis来解决 测试接口时没问题。和前端进行调试时又出现了问题,session还是取不到,查看sessionId还是在不断的变,检查redis,之前的sessionId是存进去了的,why...... 回...

6
4
发表了问答
2014/01/24 12:37

jsonp对返回的json格式报错"Uncaught SyntaxError: Unexpected token :"

用jsonp返回了一个json串后做页面填充,但是报错说json格式错误,不知道这个jsonp如何操作? jQuery(document).ready(function(){   var moviesServiceUrl="http://m.weather.com.cn/data/101010100.html";   jQuery.ajax({    dataType: "jsonp",    url: moviesServiceUrl,    jsonp: "$callback",    success: showMovies   }); }); function showMovies( data ) {   console.info("asdfasdf");   var json=JSON5.parse(data);   va...

28
1
发表了问答
2017/04/11 10:56

Jsonp跨域访问不会传输数据 求教

本人前端小白一个,遇到了跨域访问的问题,特来求教.如下为postman自动生成的jquery脚本,在postman中可用,但是放到某个html中后,访问时,会出现跨域访问拒绝的问题,如下图1所示。 var form = new FormData(); form.append("data", "[{\"serviceUrl\" : \"/bank_auth\",\"apiKey\" : \"3FE8D08DB99D326D\",\"areacode\":\"000000\"} ]"); var settings = { "async": true, "crossDomain": true, "url": "http://xxx.x...

4
0
发表了问答
2011/06/29 11:21

jQueryUI实战之Autocomplete组件的JSONP使用

作者:Terry li - GBin1.com Autocomplete是jQueryUI中新加入的俩个组件之一,它提供了方便简介的方式来自动帮助用户完成输入过程。在web前台开发过程中,我们 往往需要在搜索对话框中加入相关功能来方便用户使用。今天我们主要介绍其中跨域数据源的使用,即JSONP。下面我先简单介绍一下JSONP。 什么是JSONP JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问...

2
0
发表了问答
2016/08/12 19:48

一个页面中多个ajax同时请求后台同一个跨域json方法会报错

前台代码: function ajaxRequest1(){ $.ajax({ url:'http://127.0.0.1:8080/DevInfoWeb/get', type: "get", async: false, dataType: "jsonp", data:{ callbackparam:"callbackparam1" }, jsonpCallback: "callbackparam1", //callback的function名称,服务端会把名称和data一起传递回来 success: function(json) { alert(json); }, error: function(){alert('Error');} }); } function ajaxRequest2(){ $.ajax({ url:'http://1...

3
0
发表了问答
2016/01/02 09:55

jsonp跨域不能取值

跨域调用,在chrome调试器里返回的数据正常,可以在代码里却是进入了error函数,请问如何正常获取值呢,我是想获取别人的页面内容,不能调整别人的返回程序代码的

4
0
发表了问答
2016/07/06 18:26

无法修改服务器,jsonp总是执行error方法

调用扇贝网API,实现查词功能。利用jsonp解决跨域问题,却总是执行error中的方法。 <script type="text/javascript">   $(function(){     $("#trans").click(function(){       $.ajax({         type:"GET",         url:"https://api.shanbay.com/bdc/search/?word="+"{"+ $("#word").val()+"}",         dataType:"jsonp",         jsonp:"?",         //jsonpCallback:"successCallback",         success: function(json){           $("#result").html(dat...

16
1
发表了问答
2016/06/22 17:15

chrome插件编写。ajax请求出错

代码 运行在 content.js $.ajax({ type:'get', async:true, url:'xxxxxxxxxxxxxxxxxxxx', data:{ command:'check', sld:reg_name_array['0'], tldlist:reg_name_array['1'], flush:'false', timeout:'10000', language:'' }, dataType:'jsonp', jsonpCallback:"baogume", success:function(baogume){ alert('0') }, error:function(XMLHttpRequest,textStatus,errorThrown){ alert(XMLHttpRequest) } }) 插件执行请求。。 报错。...

4
1
发表了问答
2015/12/19 19:19

jquery ajax跨域提交能返回数据,但是出现错误

返回的状态码 ERROR: {"readyState":4,"status":200,"statusText":"success"} 以下是js 代码 $.ajax({ type:"get", async:false, url:"http://www.idcicp.com/ajax/SearchAjax.ashx?domain="+lk+"", dataType:"jsonp", jsonpCallback: 'CallBack', success:function(jsonp){ bhg=JSON.stringify(jsonp) lert(0) ...

9
0
发表了问答
2015/11/18 14:55

又来灌水啦,求问关于jsonp的问题

各位大大,我在使用jsonp的时候,发现自定义jsonp的回调函数之后,success所定义的回调函数就不执行了,求问为什么,有啥解决措施不,谢谢

4
0
发表了问答
2015/08/24 10:29

怎么捕获JSONP跨域请求的连接异常

代码如下: function jsonpTest(){ var JSONP = document.createElement("script"); JSONP.type = "text/javascript"; JSONP.src="http://xxx.abc.com/s?jsonp=callback"; document.getElementsByTagName('head')[0].appendChild(JSONP); } function callback(){ ... } 问题:如果跨域请求异常,怎么捕获到。我知道jQuery封装的JSONP可以解决,特殊原因我这里不能用jQuery.在线等!...

7
0
发表了问答
2015/06/27 11:39

JSONP 同时访问多个执行出问题

因业务需要,需同时向2个地方获取数据,采用jsonp的方式获取, 使用jquery 实现jsonp a();b() 直接这样获取会出现卡死现象,只有一个成功,有尝试过在a和b直接加上 sleep(),是可行的, 但基于浏览器不同,sleep时间又是不定,IE chorme 500毫秒就OK了,firefox则不行,这个应该 是jsonp的问题,有没有哪个大神碰到过类似的问题,求解啊

4
0
发表了问答
2015/01/17 21:12

试着抓取网易的图片报404错误

网太卡,没办法的事情, 看网易的新闻图片呢,无奈网太慢了, 基本加载不出来,急死人了. 就想着写点代码抓取图片页面的信息,然后弄个页面全部展示,这样试了下,效果还不错, 后来又想把这些信息保存到本地,直接浏览就行啦, 其实就是个json串, 也不难. 可是,可是,可是再次抓取就404了, 不知道网易是怎么判断出来我不是用的浏览器,但用浏览器还是可以访问的,我想应该是Cookie判断的,但不是很清楚. 尤其是用浏览器访问地址最后是有些参数...

2
0
发表了问答
2013/03/27 19:24

jquery jsonp 不支持async:false

如题: jquery jsonp远程调用不支持async设置为false。最终和值为true的方式一样,都是异步。不知道有没有兄弟遇见过这样的情况。其中不支持post是出于构建script的考虑,那这个呢??请高手解答!具体出于一个什么考虑?

1
0
发表了问答
2014/08/26 15:39

求救: jsonp跨域访问问题

我正在做一个和腾讯开放平台对接的项目。需要使用QQ的登陆功能,而且要获取到用户的QQ头像。 现有代码如下: var appId = '${sessionScope.openqq_appid}'; var openId = '${sessionScope.openqq_openid}'; var token = '${sessionScope.openqq_access_token}'; var get_user_info_url = "https://graph.qq.com/user/get_user_info"; var param = "oauth_consumer_key="+appId+     "&access_token="+token     +"&open...

6
3
发表了问答
2014/05/07 17:25

jsonp 跨域 解析返回结果报错

1.测试代码如下: <!DOCTYPE HTML> <html> <head> </head> <body > <input type="button" onclick="callBing()" value="load"/> </body> <script type="text/javascript"> function callback(data) { alert("s"); } function callBing(){ var JSONP=document.createElement("script"); JSONP.type="text/javascript"; JSONP.src="http://bj1.api.bing.com/qsonhs.aspx?mkt=zh-CN&q=a&jsonp=callback"; document.getElementsByTa...

4
0
发表了问答
2013/12/19 21:11

HttpClient怎么获取到iframe中的内容

我用HttpClient构造登陆表单登陆后,登陆页面中的主要内容是通过iframe加载过来的 <li><a href="login.aspx?xh=jk&xm=&gnmkdm=MM120306" target='zhuti' onclick="GetMc('登陆信息');">登陆信息</a></li> 然后我试着用HttpClient构造参数去加载iframe时,却加载不了,post提交时返回状态码302,跳转到登陆界面。 火狐的在新窗口中打开框架功能时可以打开该frame,但是刷新后就会跳转到登陆界面 请问怎样才能访问到该iframe,并获...

4
0
发表了问答
2010/04/20 17:54

关于JavaScript“跨域”问题的总结

什么是同源策略? 同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。这个浏览器策略很旧,从 Netscape Navigator 2.0 版本开始就存在。 URL 说明 是否允许通信 http://www.playgoogle.com/lab/a.js http://www.playgoogle.com/script/b.js 同一域名下不同文件夹 允许 http://www.playg...

5
24
没有更多内容
加载失败,请刷新页面
点击加载更多
加载中
下一页
1 评论
49 收藏
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部