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

使用jQuery jsonp跨域调用ASP.NET web服务,jquery,asp.net,web-services,cross-domain,jsonp,Jquery,Asp.net,Web Services,Cross Domain,Jsonp,我的问题是已知的问题,并经过讨论和讨论。 但是,即使在阅读并实施了建议的解决方案之后,我也无法实现这一目标 问题:返回xml而不是json的web服务: <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/">"Now i am getting jsop string""2nd param"</string> 现在我得到了jsop字符串“第二个参数” 现在让我们

我的问题是已知的问题,并经过讨论和讨论。 但是,即使在阅读并实施了建议的解决方案之后,我也无法实现这一目标

问题:返回xml而不是json的web服务:

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">"Now i am getting jsop string""2nd param"</string>

现在我得到了jsop字符串“第二个参数”
现在让我们将代码分成几个部分:

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

<?xml version="1.0"?>
<configuration>
        <system.webServer>
            <modules>
                <add name="JsonHttpModule.JsonHttpModule" type="JsonHttpModule"/>
            </modules>
        </system.webServer>
    <system.web.extensions>
        <scripting>
            <webServices>
                <jsonSerialization maxJsonLength="102400"/>
            </webServices>
        </scripting>
    </system.web.extensions>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
        <customErrors mode="Off"/>
        <webServices>
            <protocols>
                <add name="HttpGet"/>
                <add name="HttpPost"/>
            </protocols>
        </webServices>
    </system.web>
</configuration>


web服务:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using JsonHttpModule;
/// <summary>
/// Summary description for JSONP_EndPoint
/// </summary>
[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;
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.Web.Services;
使用System.Web.Script.Services;
使用JsonHttpModule;
/// 
///JSONP_端点的摘要说明
/// 
[WebService(命名空间=”http://tempuri.org/")]
[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
//要允许使用ASP.NET AJAX从脚本调用此Web服务,请取消注释以下行。
[System.Web.Script.Services.ScriptService]
公共类MyService:System.Web.Services.WebService{
[网络方法]
[ScriptMethod(UseHttpGet=true,ResponseFormat=ResponseFormat.Json)]
公共字符串和(字符串x、字符串y)
{
返回x+y;
}
}

HttpModule类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Text;

/// <summary>
/// Summary description for ContentTypeHttpModule
/// </summary>
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(")");
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用System.IO;
使用系统文本;
/// 
///ContentTypeHttpModule的摘要说明
/// 
命名空间JsonHttpModule
{
公共类JsonHttpModule:IHttpModule
{
私有常量字符串JSON\u CONTENT\u TYPE=“application/JSON;charset=utf-8”;
公共空间处置()
{
}
公共void Init(HttpApplication应用程序)
{
app.BeginRequest+=OnBeginRequest;
app.EndRequest+=新事件处理程序(OnEndRequest);
}
public void OnBeginRequest(对象发送方,事件参数e)
{
HttpApplication应用程序=(HttpApplication)发送方;
HttpRequest请求=app.request;
//确保我们只应用于我们的Web服务
if(request.Url.AbsolutePath.ToLower()包含(“MyService.asmx”))
{
if(string.IsNullOrEmpty(app.Context.Request.ContentType))
{
app.Context.Request.ContentType=JSON\u CONTENT\u TYPE;
}
app.Context.Response.Write(app.Context.Request.Params[“callback”]+”(“”);
}
}
void OnEndRequest(对象发送方,事件参数e)
{
HttpApplication应用程序=(HttpApplication)发送方;
HttpRequest请求=app.request;
if(request.Url.AbsolutePath.ToLower()包含(“MyService.asmx”))
{
app.Context.Response.Write(“)”;
}
}
}
}
客户端(本地主机):


$(函数(){
$(“#btn_测试”)。单击(函数(){
$.ajax({url:http://tonofweb.com/MyService.asmx/Sum",
数据:{x:JSON.stringify(“现在我得到了jsop字符串”),y:JSON.stringify(“第二个参数”)},
数据类型:“jsonp”,
成功:函数(json){
警报(json.d);
},
错误:函数(){
警报(“命中错误fn!”);
}
});
});
});
那么我做错了什么? 您可以自己测试它,这是一个实时的web服务。
感谢您的帮助。

似乎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”

我测试了这段代码,方法是浏览到(目前返回403),包括使用jQuery,然后首先运行您的问题中的代码(没有contentType),然后运行我上面发布的代码(带有contentType)

以下是Chrome开发者工具中网络选项卡的响应:

不带contentType

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">"Now i am getting jsop string""2nd param"</string>
{"d":"12"}
因此,第二个至少会导致从服务器返回JSON。在其他条件相同的情况下,我想添加contentType

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

HTTP请求必须声明application/json的内容类型。这 通知ScriptService它将以JSON形式接收其参数 它应该以同样的方式作出回应

现在您还有另一个问题,那就是请求在完成时调用error函数。如果将
数据类型:“jsonp”
更改为
数据类型:“json”
它将调用success函数。因此,回调包装器的实现有些地方是错误的,因为jQuery不能将响应作为JSONP处理

现在,我也没有看到响应中包含回调,对于JSONP,响应应该类似于:

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

我注意到您正在链接到关于如何从web服务执行JSONP响应的,但您没有遵循建议:您不使用
response.Filter
,而是使用
response.Write

是的,它正在工作,您说:“问题是:web服务返回xml而不是json:”。我刚刚测试了这段代码,如果您只添加了
contentType:“application/JSON;charset=utf-8”
,您的web服务就会用JSON响应,即使我添加了contentType:“application/JSON;charset=utf-8”我得到:“1”“2”请按照我的步骤操作
jQuery17106476630216930062_1326752446188({"d":"12"})