ASP.NET 跨域请求之jQuery的ajax jsonp的使用解惑 (转载)

Posted PowerCoder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET 跨域请求之jQuery的ajax jsonp的使用解惑 (转载)相关的知识,希望对你有一定的参考价值。

前天在项目中写的一个ajax jsonp的使用,出现了问题:可以成功获得请求结果,但没有执行success方法,直接执行了error方法提示错误——ajax jsonp之前并没有用过,对其的理解为跟普通的ajax请求差不多,没有深入了解;出现了这种错误,几经调试(检查后台的代码和js部分的属性设置)还是不行,让我感觉很是意外和不解。于是,决定仔细研究下ajax jsonp的使用,并将最后测试成功的学习经验和大家分享下!

 

首先,贴出可以成功执行的代码:

(页面部分)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
     <script type="text/javascript">
    jQuery(document).ready(function(){
        $.ajax({
            type : "get",
            async:true,
            url : "ajax.ashx",
            dataType : "jsonp",
            jsonp: "callbackparam",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
            jsonpCallback:"success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
            success : function(json){
                alert(json);
                alert(json[0].name);
            },
            error:function(){
                alert(\'fail\');
            }
        });
        var a="firstName Brett";
        alert(a);
    });
    </script>
    </head>
 <body>
 </body>
</html>

 

(处理程序部分)

<%@ WebHandler Language="C#" Class="ajax" %>

using System;
using System.Web;

public class ajax : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";//注意这里必须要声明HttpResponse的返回类型为text/plain,否者前面在使用jquery的ajax方法调用jsonp时会一直走error方法,提示"fail"

        string callbackFunName = context.Request["callbackparam"];
        context.Response.Write(callbackFunName + "([ { name:\\"John\\"} ] )");
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

(请求抓包截图)

 

 

Ajax请求参数说明:

dataType  String

预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如XML MIME类型就被识别为XML。在1.4中,JSON就会生成一个JavaScript对象,而script则会执行这个脚本。随后服务器端返回的数据会根据这个值解析后,传递给回调函数。可用值:

"xml": 返回 XML 文档,可用 jQuery 处理。

"html": 返回纯文本 HTML 信息;包含的script标签会在插入dom时执行。

"script": 返回纯文本 JavaScript 代码。不会自动缓存结果。除非设置了"cache"参数。\'\'\'注意:\'\'\'在远程请求时(不在同一个域下),所有POST请求都将转为GET请求。(因为将使用DOM的script标签来加载)

"json": 返回 JSON 数据 。

"jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。

"text": 返回纯文本字符串

 

jsonp   String

在一个jsonp请求中重写回调函数的名字。这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,比如{jsonp:\'onJsonPLoad\'}会导致将"onJsonPLoad=?"传给服务器。

 

jsonpCallback   String

为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。这主要用来让jQuery生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。

 

ajax jsonp与普通的ajax请求的主要区别在于——请求响应结果的处理。如上面代码所示的响应结果为:  success_jsonpCallback([ { name:"John"} ] ); ————其实就是,调用jsonp回调函数success_jsonpCallback,并将要响应的字符串或json传入此方法(作为参数值),其底层的实现,大概的猜想应该是:  

function success_jsonpCallback(data)  {      success(data);  }

 

经测试,ajax jsonp对同步或异步请求没有影响。

 

 

注意jsonp处理程序的Http返回类型必须是text/plain

前面我们在处理程序的代码里面写了HttpResponse的返回类型必须是text/plain,否者前台jquery在调用ajax方法jsonp的时候会报错,这是为什么呢?

原因是jsonp是通过在前台浏览器页面中声明一个script标签,然后将标签的src属性设置为jquery的ajax方法中url参数的地址,来实现跨域ajax请求的,其根本是运用了html的script标签可以跨域访问url地址这个特性。而script标签要求其src地址返回内容的Content-Type必须是text/plain,否者前段html页面会报错。所以这就要求我们在后端处理程序中要声明HttpResponse的返回类型必须是text/plain。

 

例如,如果你在后台使用了ASP.NET WebApi作为jsonp的处理程序,那么就要构造一个HttpResponseMessage对象,将返回的内容包装进HttpResponseMessage,声明其mediaType(即Content-Type)是text/plain:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;

namespace JsonpServer.Controllers
{
    public class HelloWorldController : ApiController
    {
        public HttpResponseMessage Get()
        {
            HttpResponseMessage responseMessage = Request.CreateResponse(HttpStatusCode.OK);
            responseMessage.Content = new StringContent("success_jsonpCallback(\'Hello world!\')",Encoding.UTF8, "text/plain");
            return responseMessage;
        }
    }
}

这样WebApi返回的Http类型就会是text/plain了。

 

再贴出在WCF中将Reponse的Content-Type改为text/plain的方法,很简单在WCF方法中调用WebOperationContext对象即可:

WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";

 

反正记住不管你后台是MVC、WebApi、WCF还是WebService等,都要保证其后台处理程序返回的HttpResponse的Content-Type为text/plain,这样前台javascript调用jsonp才不会报错!

 

原文链接

 

以上是关于ASP.NET 跨域请求之jQuery的ajax jsonp的使用解惑 (转载)的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 实现AJAX跨域请求的两种方法

JQuery Ajax POST/GET 请求至 ASP.NET WebAPI

Jquery AJAX ASP.NET IIS 跨域 超简单解决办法

ASP.NET MVC 实现AJAX跨域请求方法《1》

ASP.NET网站中实现Ajax的跨域请求

ASP.NET WebForm 之 Ajax 请求后端处理