我了解JSON,但不了解JSONP。 Wikipedia上有关JSON的文档是JSONP的最高搜索结果。 它说: javascript
JSONP或“带填充的JSON”是JSON扩展,其中将前缀指定为调用自己的输入参数。 php
?? 什么电话 这对我来讲毫无心义。 JSON是一种数据格式。 没有电话 html
第二个搜索结果来自一个叫Remy的人 ,他写了关于JSONP的代码: java
JSONP是脚本标记注入,它未来自服务器的响应传递到用户指定的函数。 json
我能够理解,但这仍然没有任何意义。 api
那么JSONP是什么? 为何建立它(它解决了什么问题)? 我为何要使用它? 跨域
附录 :我刚刚在Wikipedia 上为JSONP建立了一个新页面 。 根据jvenema的回答,它如今对JSONP有了清晰而透彻的描述。 浏览器
JSONP经过构造一个“脚本”元素(以HTML标记或经过JavaScript插入DOM)来工做,该元素请求到远程数据服务位置。 响应是使用预约义函数名称以及所传递的参数(即请求的JSON数据)加载到浏览器上的JavaScript。 执行脚本时,该函数将与JSON数据一块儿调用,从而容许请求页面接收和处理数据。 安全
有关进一步的阅读访问, 请 访问: https : //blogs.sap.com/2013/07/15/secret-behind-jsonp/ 服务器
客户端代码段
<!DOCTYPE html> <html lang="en"> <head> <title>AvLabz - CORS : The Secrets Behind JSONP </title> <meta charset="UTF-8" /> </head> <body> <input type="text" id="username" placeholder="Enter Your Name"/> <button type="submit" onclick="sendRequest()"> Send Request to Server </button> <script> "use strict"; //Construct the script tag at Runtime function requestServerCall(url) { var head = document.head; var script = document.createElement("script"); script.setAttribute("src", url); head.appendChild(script); head.removeChild(script); } //Predefined callback function function jsonpCallback(data) { alert(data.message); // Response data from the server } //Reference to the input field var username = document.getElementById("username"); //Send Request to Server function sendRequest() { // Edit with your Web Service URL requestServerCall("http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message="+username.value+""); } </script> </body> </html>
服务器端的一段PHP代码
<?php header("Content-Type: application/javascript"); $callback = $_GET["callback"]; $message = $_GET["message"]." you got a response from server yipeee!!!"; $jsonResponse = "{\"message\":\"" . $message . "\"}"; echo $callback . "(" . $jsonResponse . ")"; ?>
JSONP能够很好地解决跨域脚本错误。 您能够只使用JS来使用JSONP服务,而没必要在服务器端实现AJAX代理。
您可使用b1t.co服务查看其工做方式。 这是一项免费的JSONP服务,可以让您缩小URL。 这是用于服务的网址:
http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]
例如,呼叫http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com
会回来
whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});
所以,当将该get做为src加载到您的js中时,它将自动运行您应将其实现为回调函数的任何JavascriptName:
function minifyResultsCallBack(data) { document.getElementById("results").innerHTML = JSON.stringify(data); }
要真正进行JSONP调用,您能够经过几种方式(包括使用jQuery)来实现,但这是一个纯JS示例:
function minify(urlToMinify) { url = escape(urlToMinify); var s = document.createElement('script'); s.id = 'dynScript'; s.type='text/javascript'; s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url; document.getElementsByTagName('head')[0].appendChild(s); }
这篇文章提供了一个分步示例和一个jsonp Web服务进行练习:
由于您能够要求服务器将前缀附加到返回的JSON对象。 例如
function_prefix(json_object);
为了使浏览器eval
“内联” JSON字符串做为表达式。 此技巧使服务器能够直接在客户端浏览器中“注入” javascript代码,而且绕过了“相同来源”限制。
换句话说,您能够进行跨域数据交换 。
一般, XMLHttpRequest
不容许直接进行跨域数据交换(须要经过同一域中的服务器),而:
<script src="some_other_domain/some_data.js&prefix=function_prefix
>`人们能够从不一样于来源的域访问数据。
一样值得注意的是:即便在尝试这种“技巧”以前,应将服务器视为“受信任的”服务器,也能够包含对象格式等可能发生变化的反作用。 若是使用function_prefix
(即适当的js函数)来接收JSON对象,则该函数能够在接受/进一步处理返回的数据以前执行检查。
实际上并不太复杂...
假设您使用的是example.com
域,而且想向example.net
域发出请求。 要作到这一点,你须要跨域边界, 无无多数browserland的。
绕过此限制的一项是<script>
标记。 使用脚本标记时,将忽略域限制,可是在正常状况下,您实际上没法对结果作任何事情,只是对脚本进行了评估。
输入JSONP
。 当您向启用JSONP的服务器发出请求时,您将传递一个特殊参数,该参数告诉服务器有关您页面的一些信息。 这样,服务器就能够用页面能够处理的方式很好地包装其响应。
例如,假设服务器须要一个名为callback
的参数来启用其JSONP功能。 而后您的请求将以下所示:
http://www.example.net/sample.aspx?callback=mycallback
没有JSONP,这可能会返回一些基本的JavaScript对象,以下所示:
{ foo: 'bar' }
可是,使用JSONP时,服务器收到“ callback”参数时,其包装结果会有所不一样,返回以下所示:
mycallback({ foo: 'bar' });
如您所见,它如今将调用您指定的方法。 所以,在页面中,您定义了回调函数:
mycallback = function(data){ alert(data.foo); };
如今,加载脚本后,将对其进行评估,而后将执行您的函数。 瞧,跨网域要求!
值得注意的是JSONP的一个主要问题:您失去了对请求的大量控制。 例如,没有“不错”的方法来找回正确的故障代码。 结果,您最终会使用计时器来监视请求等,这老是让人怀疑。 JSONRequest的主张是一个很好的解决方案,它容许跨域脚本编写,维护安全性并容许对请求的适当控制。
现在(2015年),与JSONRequest相比, CORS是推荐的方法。 JSONP对于较旧的浏览器支持仍然有用,可是考虑到安全隐患,除非您别无选择,不然CORS是更好的选择。
一个使用JSONP的简单示例。
client.html
<html> <head> </head> body> <input type="button" id="001" onclick=gO("getCompany") value="Company" /> <input type="button" id="002" onclick=gO("getPosition") value="Position"/> <h3> <div id="101"> </div> </h3> <script type="text/javascript"> var elem=document.getElementById("101"); function gO(callback){ script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'http://localhost/test/server.php?callback='+callback; elem.appendChild(script); elem.removeChild(script); } function getCompany(data){ var message="The company you work for is "+data.company +"<img src='"+data.image+"'/ >"; elem.innerHTML=message; } function getPosition(data){ var message="The position you are offered is "+data.position; elem.innerHTML=message; } </script> </body> </html>
server.php
<?php $callback=$_GET["callback"]; echo $callback; if($callback=='getCompany') $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})"; else $response="({\"position\":\"Development Intern\"})"; echo $response; ?>