使用jQuery jsonp跨域调用ASP.NET Web服务

我的问题是已知的问题,在这里和这里讨论。 但即使在阅读并实施建议的解决方案后,我也无法完成这项工作。

问题 :返回xson的xml的web服务:

 "Now i am getting jsop string""2nd param" 

现在让我们将代码分成几部分:

远程服务器(IIS 7.0,.NET 4):
web.config中:

                          

网络服务:

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.Web.Script.Services; using JsonHttpModule; ///  /// Summary description for JSONP_EndPoint ///  [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. [System.Web.Script.Services.ScriptService] public class MyService : System.Web.Services.WebService { [WebMethod] [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] public string Sum(string x, string y) { return x + y; } } 

HttpModule类:

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; using System.Text; ///  /// Summary description for ContentTypeHttpModule ///  namespace JsonHttpModule { public class JsonHttpModule : IHttpModule { private const string JSON_CONTENT_TYPE = "application/json; charset=utf-8"; public void Dispose() { } public void Init(HttpApplication app) { app.BeginRequest += OnBeginRequest; app.EndRequest += new EventHandler(OnEndRequest); } public void OnBeginRequest(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; HttpRequest request = app.Request; //Make sure we only apply to our Web Service if (request.Url.AbsolutePath.ToLower().Contains("MyService.asmx")) { if (string.IsNullOrEmpty(app.Context.Request.ContentType)) { app.Context.Request.ContentType = JSON_CONTENT_TYPE; } app.Context.Response.Write(app.Context.Request.Params["callback"] + "("); } } void OnEndRequest(object sender, EventArgs e) { HttpApplication app = (HttpApplication)sender; HttpRequest request = app.Request; if (request.Url.AbsolutePath.ToLower().Contains("MyService.asmx")) { app.Context.Response.Write(")"); } } } } 

客户端(localhost):

  $(function () { $('#btn_test').click(function () { $.ajax({ url: "http://tonofweb.com/MyService.asmx/Sum", data: { x: JSON.stringify("Now i am getting jsop string"), y: JSON.stringify("2nd param") }, dataType: "jsonp", success: function (json) { alert(json.d); }, error: function () { alert("Hit error fn!"); } }); }); });   

那我在这里做错了什么? 你可以自己测试它是一个实时的网络服务。 谢谢您的帮助。

似乎Web服务返回JSON的所有配置和属性都已到位,但我在您的jQuery请求中注意到,您没有指定要传入的数据的内容类型。我已将其添加到下面的代码中:

 $.ajax({ url: "http://tonofweb.com/MyService.asmx/Sum", contentType: "application/json; charset=utf-8", data: { x: JSON.stringify("1"), y: JSON.stringify("2") }, dataType: "jsonp", success: function (json) { alert(json.d); }, error: function () { alert("Hit error fn!"); } }); 

注意我在请求设置中添加了contentType: "application/json; charset=utf-8",

我已经通过浏览http://tonofweb.com (目前返回403)测试了这段代码,包括使用jQuerify bookmarklet的 jQuery,然后首先运行你的问题中的代码( 没有 contentType),然后我在上面发布的代码( 使用 contentType)。

以下是Chrome开发者工具中“网络”标签的回复:

没有contentType

  "Now i am getting jsop string""2nd param" 

使用contentType

 {"d":"12"} 

所以第二个至少会导致从服务器返回JSON。 所以其他条件相同,我会说添加contentType。

有关返回JSON的要求的说明,请参见此处:

ASMX和JSON – 常见错误和误解

HTTP请求必须声明application / json的内容类型。 这会通知ScriptService它将以JSONforms接收其参数,并且它应该以实物forms响应。

现在您还有另一个问题,那就是请求在完成时调用错误函数。 如果将dataType: "jsonp"更改为dataType: "json" ,它将调用success函数。 所以关于你的回调包装器的实现是错误的,因为jQuery不能像JSONP那样处理响应。

现在我没有看到响应中包含回调,对于JSONP,响应应该是这样的:

 jQuery17106476630216930062_1326752446188({"d":"12"}) 

我注意到你链接到这篇关于如何从Web服务做一个JSONP响应的post ,但是你没有遵循这个建议:你不使用Response.Filter ,而是使用Response.Write