简单理解jsonp原理

对于javascript程序员来说,发送ajax请求获取后台数据然后把数据和模板拼接成字符串渲染回DOM实现无刷新更新页面这样的操作可谓是轻车熟路。但众所周知,ajax有一个不好,就是不能跨域传输数据,而跨域传输有时候又是必须用到的,比如我们可能需要调用第三方网站提供的某些API来获取某些信息,提供给我们网站的用户。

例如,要开发一个天气应用,你可能需要调用第三方的天气API,这个时候就必然涉及到跨域请求数据,因为毕竟我们不可能为了开发一个天气应用就自己搭建一个天气API。在少数情况下,如果第三方网站的服务器上设置了CORS请求头,这时是可以直接用ajax发送请求的。但在大多数情况下,第三方网站都没有这么慷慨,因为涉及到安全问题,不可能允许任意人都能自由调用自己网站的接口。这个时候jsonp就应运而生了。

在HTML中有这样一类标签,它们都有一个src属性,src属性的值是一个链接,当标签一被解析到DOM中,就会开始把src属性中的链接指向的资源下载到本文档,例如,设置了src的img标签会自动从src属性的链接中下载资源,下载的资源又会被浏览器解析成图片,加到DOM中;设置了src属性的iframe元素会从src链接里下载一张网页;设置了src属性的script元素也会自动从src链接里下载javascript代码并执行,而这个过程中DOM本身也是没有刷新的,更令人心动的是,src属性的链接根本没有同域的限制。这个原理就是实现JSONP的基石。

但是,我们想用它来实现跨域还很有难度。这个src属性的元素的加载和一般的ajax请求有一个很大的不同,回想一下,在一个典型的ajax请求中,我们可以完全控制请求的过程,我们可以对指定的网页实行open,可以设置请求头,可以指定响应的MIMEtype,关键的是,我们可以从xhr对象的responseText属性中获取响应数据,然后拼接模板,渲染DOM。但在img, iframe, script这些标签中呢,我们的控制权就被剥夺了,我们设置src属性,浏览器负责发送请求,服务器端返回的响应直接就被加载回DOM了,我们根本没有插手修改数据的机会。

怎么办呢?这就像向遥远的深空发射一艘飞船,当飞船远离我们几十光年的时候,我们就不太可能从地面对它发送实时控制信号了,更好的做法就是把指令提前写在飞船上,让它自动执行。

和飞船的例子一样,一个典型的jsonp过程就是:创建一个script标签,设置src属性,这个src属性中包括了目标API的地址,我们的查询字符串querystring,querystring中最最重要的是我们的“指令”,因为script标签src返回之后,我们并不能控制返回的结果,所以最好让服务器返回的时候自己执行我们想要执行的操作。这个“指令”也就是jsonp中的“p”了。

举一个栗子:

1.我需要某个数据,比如就按照前面讲的,天气数据吧,于是我构造查询url。

var script = document.createElement(‘script‘);
script.src = ‘www.weather.fake/get/?province=hubei&city=wuhan&callback=instruction‘;
document.getElementsByTagName(‘head‘)[0].appendChild(script);//先写好指令,即回调
function instruction(data){
    console.log(data);
}
//注意这里的instruction就是我们告诉服务器的“指令”。我们跟服务器说,我需要province为hubei,city为wuhan的地方的天气数据,但由于数据返回后我自己不能处理,所以你返回数据的时候自己处理好了,具体怎么处理,我已经写在名字叫做instruction的指令里面了。 

2.weather.fake的服务器收到我的请求,从数据库里一找,找到了数据。一看,还有个指令,于是它就执行instruction指令。说起来很高级,实际上也就是把返回的数据包裹在instruction函数里面(jsonp的p,padding)。服务器于是返回这样一个东西:

//response.js
instruction({  "city":"wuhan",  "weather":"cloudy"}) 

3.服务器端的writeheader设置和浏览器端的accept设置会保证返回的东西会被浏览器解释成一个js文件,于是我们事先写好的指令instruction函数就得到了执行,整个jsonp过程就完成了。

需要注意的几点:

1.返回的js文件是在全局作用域执行的,所以你要保证你写的回调函数instruction在全局作用域里。

2.这里的callback=instruction。其中,callback只是一个普通的querystring,是你和服务器事先约定的,不同API提供方,名字也不同,有的可能就叫cb,等等。至于instruction,你爱写什么写什么,但要保证和你写的回调处理函数名字一致。我这里为了方便理解,就写instruction了。

3.ajax跨域,危险在哪里?

有些人说,禁止ajax跨域,是为了防止攻击者利用它向自己的服务器发送敏感信息(例如cookie等等),这显然是错误的。对于一个已经被注入攻击代码的网站,攻击者如果只是想向自己的服务器发送信息而已,就算不用ajax,也完全可以用img等标签直接向自己的服务器执行get请求发送数据,况且创建一个img标签可比写一个完整的ajax过程简单多了,根本用不着兴师动众,也就是说,单向GET请求ajax并没有优势。

为什么要限制ajax,因为它太强大了。看看CORS机制,它规定的是服务器方面的接受白名单。也就是说,由服务器来决定可以接受哪些客户可以向它请求数据。说明跨域限制主要是为了保证服务器端安全的。

一般能用src做到的,ajax都能做到,ajax能做到的src却不一定能够做到。例如src只能发起get请求,但ajax能发起任意类型的请求。

举个栗子,某博客网站的删除功能API可能必须要用DELETE方法发送请求才能执行,这个时候攻击者如果只用src就无能为力了,但ajax却可以轻易模拟用户动作。这个时候禁止跨域就显得很重要了。

时间: 2024-08-06 00:41:01

简单理解jsonp原理的相关文章

深入理解JSONP原理——前端面试

JSON和JSONP虽然只有一个字之差,但是它们俩是八竿子打不着的:JSON是一种数据交换格式,JSONP是非正式的跨域数据交换协议. 为什么说JSONP是非正式的传输协议呢?因为它就是利用了<script>标签没有跨域限制这一"漏洞"来达到与第三方通讯的目的.简单地说,该协议就是,允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名包裹json数据,这样客户端就可以随意定制自己的函数自动处理返回的数据了. 即,需要通讯时

一文简单理解“推荐系统”原理及架构

本文主要介绍什么是推荐系统,为什么需要推荐系统,如何实现推荐系统的方案,包括实现推荐系统的一些常见模型,希望给读者提供学习实践参考. 为什么需要推荐系统                         对于信息消费者,需要从大量信息中找到自己感兴趣的信息,而在信息过载时代,用户难以从大量信息中获取自己感兴趣.或者对自己有价值的信息. 对于信息生产者,需要让自己生产的信息脱颖而出,受到广大用户的关注.从物品的角度出发,推荐系统可以更好地发掘物品的长尾(long tail). 长尾效应是美国<连线>

简单理解ThreadLocal原理和适用场景

https://blog.csdn.net/qq_36632687/article/details/79551828?utm_source=blogkpcl2 参考文章: 正确理解ThreadLocal 一个故事讲明白 ThreadLocal 原文地址:https://www.cnblogs.com/zt007/p/9797762.html

[转帖]mDNS原理的简单理解

mDNS原理的简单理解 https://binkery.com/archives/318.html 发现还有avahi-daemon mdns 设置ip地址 等等事项 网络部分 自己学习的还是不够多 ,需要加强学习. Android,Java,DNS,局域网,mDNS,组播,Java mDNS,Multicast DNS,mDNS原理,mDNS组播 2016-03-21 08:53:39 mDNS , multicast DNS, 可以理解为局域网内部的 DNS 系统,它和 DNS 有很多相似的

深入理解jsonp跨域请求原理

在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据.解决ajax的跨域问题有两种方法: 一.jsop 二.XMLHttpRequest2中可以配合服务端来解决,在响应头中加入Access-Control-Allow-Origin:* 1.同源: 同源策略是浏览器的一种安全策略,所谓同源是指,域名,协议,端口号完全相同 1.1目的:保护用户信息安全 1.2限制:cookie.localStorage和IndexDB无法读取 无法操作跨域

JSONP原理及其简单封装

什么是JSONP 1.一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面.动态网页.web服务.WCF,只要是跨域请求,一律不准: 2.不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>.<img>.<iframe>): 3.于是可以判断,当前阶段如果想通过纯web端(ActiveX控件.服务端代理.属于未来的H

JSONP原理,怎样实现跨域?

什么是JSONP? JSONP和JSON的关系又是什么呢? JSON(JavaScript Object Notation)和JSONP(JSON with Padding)虽然只有一个字母的差别,但其实他们根本不是一回事儿:JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议.我们拿最近比较火的谍战片来打个比方,JSON是地下党们用来书写和交换情报的"暗号",而JSONP则是把用暗号书写的情报传递给自己同志时使用的接头方式.看到没?一

解决Ajax 跨域问题 - JSONP原理解析

解决Ajax 跨域问题 - JSONP原理解析 为什么会有跨域问题? - 因为有同源策略 同源策略是浏览器的一种安全策略,所谓同源指的是 请求URL地址中的 协议, 域名 和 端口 都相同,只要其中之一不相同就是跨域 同源策略主要为了保证浏览器的安全性 在同源策略下,浏览器**不允许**Ajax跨域获取服务器数据 http://www.example.com/detail.html 跨域请求: http://api.example.com/detail.html 域名不同 http://www.

AJAX(六)jsonp原理详解

一.什么是jsonp? 先别管什么叫jsonp,我们先来看一个小问题,看完这个问题你就知道jsonp是要解决什么问题的,自然也就明白什么是jsonp了. 问题: 之前做的例子如果在同一个域名下运行时是非常正常的,但如果这个数据接口是在A域名下,而使用了AJAX请求的静态页运行在B域名下,我们就会发现点击按钮发出请求时会报错.截个图来看看. 我们看到后台的一般处理程序运行的域名是 : http://localhost:64113 现在使用VS重新创建1个web项目,然后在这个使用AJAX方式发出请