比较不错的两篇文章:
1.
http://www.cnblogs.com/benwu/archive/2012/12/25/2832981.html
function TestAjax()
{
$.ajax({
type : "get",
async : false,
url : "ajaxHandler.ashx", //实际上访问时产生的地址为: ajax.ashx?callbackfun=jsonpCallback&id=10
data : {id : 10},
cache : false, //默认值true
dataType : "jsonp",
jsonp: "callbackfun",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
jsonpCallback:"jsonpCallback",
//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
//如果这里自定了jsonp的回调函数,则success函数则不起作用;否则success将起作用
success : function(json){
alert(json.message);
},
error:function(){
alert("erroe");
}
});
}
function jsonpCallback(data) //回调函数
{
alert(data.message); //
}
public class ajaxHandler : IHttpHandler
{
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
string callbackfun = context.Request["callbackfun"];
context.Response.Write(callbackfun + "({name:\"John\", message:\"hello John\"})");
context.Response.End();
}
public bool IsReusable {get {return false;}
}
---
ajax请求参数说明:
dataType string 服务器返回的数据类型。
如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如XML MIME类型就被识别为XML。
可用值:
"xml": 返回 XML 文档,可用 jQuery 处理。
"html": 返回纯文本 HTML 信息;包含的script标签会在插入dom时执行。
"script": 返回纯文本 JavaScript 代码。不会自动缓存结果。除非设置了"cache"参数。
注意:在远程请求时(不在同一个域下),所有POST请求都将转为GET请求。(因为将使用DOM的script标签来加载)
"json": 返回 JSON 数据 。
"text": 返回纯文本字符串
"jsonp":jsonp格式。使用jsonp形式调用函数时,
访问url时会自动将url后面添加上如"callback=callbackFunName" 以执行回调函数(callbackFunName)。
jsonp string
在一个jsonp请求中重写回调函数的名字。这个值用来替代在"callback=?"这种get或post请求中url参数里的"callback"部分,
比如 jsonp:'callbackfun' 则将会生成"callbackfun=?"传给服务器。
jsonpCallback String 此参数为jsonp请求指定一个回调函数名。
这个值将用来取代jQuery自动生成的随机函数名。 即上面"callback=?"中的问号部分
这主要用来让jQuery生成度独特的函数名,这样请求更容易,也能方便地提供回调函数和错误处理。
也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。
ajax jsonp与普通的ajax请求的主要区别在于——请求响应结果的处理。如上面代码所示的响应结果为:
jsonpCallback({ name:"world",message:"hello world"});
实际上就是调用jsonp回调函数jsonpCallback,并将要响应的字符串或json传入此方法,
关于自定了jsonp的回调函数, success函数则不起作用
大概其底层的实现(当然这是默认的回调函数的时候,否则就不会执行success的方法吧):
function default_jsonpCallback(data)
{
success(data); //在默认的回调方法中执行
}
最后一个比较简单的方法,
$.getJSON("GetUserbyName.aspx?name=ww&callback=?",
function(date)
{
//....
}
)
2. http://www.clanfei.com/2012/08/1637.html
跨域的解决方案有多种,其中最常见的是使用同一服务器下的代理来获取远端数据,再通过ajax进行读取,而在这期间经过了两次请求过程,使得获取数据的效率大大降低,这篇文章蓝飞就为大家介绍一下解决跨域问题的一种比较通用的方案——JSONP。
什么是跨域?
简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即“同源策略”。而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果。
具体策略限制情况可看下表:
URL | 说明 | 允许通信 |
http://www.a.com/a.js http://www.a.com/b.js | 同一域名下 | 允许 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js | 同一域名下不同文件夹 | 允许 |
http://www.a.com:8000/a.js http://www.a.com/b.js | 同一域名,不同端口 | 不允许 |
http://www.a.com/a.js https://www.a.com/b.js | 同一域名,不同协议 | 不允许 |
http://www.a.com/a.js http://127.0.0.100/b.js | 域名和域名对应ip | 不允许 |
http://www.a.com/a.js http://script.a.com/b.js | 主域相同,子域不同 | 不允许 |
http://www.a.com/a.js http://a.com/b.js | 同一域名,不同二级域名(同上) | 不允许 |
http://www.a.com/a.js http://www.b.com/b.js | 不同域名 | 不允许 |
什么是JSONP?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,而JSONP(JSON with Padding)则是JSON 的一种“使用模式”,通过这种模式可以实现数据的跨域获取。
JSONP跨域的原理
在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。
举个例子,假如需要从服务器(http://www.a.com/user?id=123)获取的数据如下:
- {"id": 123, "name" : "张三", "age": 17}
那么,使用JSONP方式请求(http://www.a.com/user?id=123?callback=foo)的数据将会是如下:
- foo({"id": 123, "name" : "张三", "age": 17});
当然,如果服务端考虑得更加充分,返回的数据可能如下:
- try{foo({"id": 123, "name" : "张三", "age": 17});}catch(e){}
以PHP为例,服务端的代码应该如下:
- $json = json_encode(array("id" => 123, "name" => "张三", "age" => 17));
- if(isset($_GET['callback'])){
- $json = 'try{' . $_GET['callback'] . '(' . $json . ')}catch(e){}';
- }
- echo $json;
这时候我们只要定义一个foo()函数,并动态地创建一个script标签,使其的src属性为http://www.a.com/user?id=123?callback=foo:
- <script type="text/javascript" src="http://www.a.com/user?id=123?callback=foo"></script>
便可以使用foo函数来调用返回的数据了。
在jQuery中如何通过JSONP来跨域获取数据
第一种方法是在ajax函数中设置dataType为'jsonp':
- $.ajax({
- dataType: 'jsonp',
- url: 'http://www.a.com/user?id=123',
- success: function(data){
- //处理data数据
- }
- });
第二种方法是利用getJSON来实现,只要在地址中加上callback=?参数即可:
- $.getJSON('http://www.a.com/user?id=123&callback=?', function(data){
- //处理data数据
- });
也可以简单地使用getScript方法:
- //此时也可以在函数外定义foo方法
- function foo(data){
- //处理data数据
- }
- $.getScript('http://www.a.com/user?id=123&callback=foo');
JSONP的应用
JSONP在开放API中可以起到非常重要的作用,开放API一般是运用于开发者的应用上,而这些应用往往是在开发者的服务器上而并非在新浪微博的服务器上,因此跨域请求数据成为前端开发者们所需要解决的一大问题,广大开放平台应该实现对JSONP的支持,这一点新浪微博开放平台便做的非常好(虽然某些API里没有说明,但实际上是可以使用JSONP方式调用的)。