JSONP解释
JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。另一个解决这个问题的新方法是跨来源资源共享。 由于同源策略,一般来说位于server1.example.com的网页无法与 server2.example.com的服务器沟通,而HTML的 目录[隐藏]
原理[编辑]为了理解这种模式的原理,先想像有一个回传JSON文件的URL,而JavaScript 程序可以用XMLHttpRequest跟这个URL要数据。假设我们的URL是 http://server2.example.com/RetrieveUser?UserId=xxx 。假设小明的UserId 是1823,且当浏览器通过URL传小明的UserId,也就是抓取http://server2.example.com/RetrieveUser?UserId=1823,得到: {"Name": "小明", "Id" : 1823,33);">"Rank"7}
这个JSON数据可能是依据传过去URL的查询参数动态产生的。 这个时候,把<script>元素的src属性设成一个回传JSON的URL是可以想像的,这也代表从HTML页面通过script元素抓取 JSON是可能的。 然而,一份JSON文件并不是一个JavaScript程序。为了让浏览器可以在<script>元素运行,从src里URL 回传的必须是可执行的JavaScript。在JSONP的使用模式里,该URL回传的是由函数调用包起来的动态生成JSON,这就是JSONP的“填充(padding)”或是“前辍(prefix)”的由来。 惯例上浏览器提供回调函数的名称当作送至服务器的请求中命名查询参数的一部分,例如: <script type="text/javascript"
src"http://server2.example.com/RetrieveUser?UserId=1823&jsonp=parseResponse">
</script>
服务器会在传给浏览器前将JSON数据填充到回调函数(parseResponse)中。浏览器得到的回应已不是单纯的数据叙述而是一个脚本。在本例中,浏览器得到的是: parseResponse({7})
填充[虽然这个填充(前辍)“通常”是浏览器运行背景中定义的某个回调函数,它也可以是变量赋值、if叙述或者是其他JavaScript叙述。JSONP要求(也就是使用JSONP模式的请求)的回应不是JSON也不被当作JSON解析——回传内容可以是任意的表达式,甚至不需要有任何的JSON,不过惯例上填充部分还是会触发函数调用的一小段JavaScript片段,而这个函数调用是作用在JSON格式的数据上的。
也因为这样,JSONP被称作是一种“让用户利用script元素注入的方式绕开同源策略”的方法。 安全问题[使用远程网站的script标签会让远程网站得以注入任何的内容至网站里。如果远程的网站有JavaScript注入漏洞,原来的网站也会受到影响。
只有在该JSON数据含有不该泄漏给第三方的隐密数据,且服务器仅靠浏览器的同源策略阻挡不正常要求的时候这才会是问题。若服务器自己决定要求的专有性,并只在要求正常的情况下输出数据则没有问题。只靠Cookie并不够决定要求是合法的,这很容易受到跨站请求伪造攻击。 |