跨域调用jQuery jsonp到ASP。净web服务

时间:2021-10-25 12:20:46

My problem is known issue and discussed here and here. But even after reading and implementing the suggested solutions i am unable to make this work.

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

The problem: the web service returning xml insted of json:

问题:返回json标记的xml的web服务:

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

Now lets break the code into sections:

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

THE REMOTE SERVER (IIS 7.0, .NET 4):
web.config:

远程服务器(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>


the web service:

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;
    }

}


the HttpModule class:

step 4类:

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(")");
            }
        }
    }
}

CLIENT SIDE (localhost):

客户端(localhost):

<script>
    $(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!");
                }
            });
    });
});
</script>
    <input id="btn_test" type="button" value="POST" />

so what am i doing wrong here? you can test it yourselves it's a live web service. Thank you for your help.

我做错了什么?您可以自己测试它,它是一个实时web服务。谢谢你的帮助。

1 个解决方案

#1


8  

It seems all the configuration and attributes are in place for the web service to return JSON but I did notice in your jQuery request, you are not specifying the content type of the data you are passing in. I have added it to the code below:

看起来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!");
  }
});

Notice I added contentType: "application/json; charset=utf-8", to the request settings.

注意,我添加了contentType:“application/json;到请求设置时,charset=utf-8。

I have tested this code by browsing to http://tonofweb.com (which returns a 403 at the moment), including jQuery using the jQuerify bookmarklet, and then running the code from your question first (without the contentType), and then the code I posted above (with the contentType).

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

Here are the responses from the Network tab in the Chrome Developer Tools:

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

Without contentType:

没有contentType:

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

With contentType:

contentType:

{"d":"12"}

So the second one at least results in JSON being returned from the server. So all else being equal, I'd say add the contentType.

因此第二个至少会导致从服务器返回JSON。在其他条件都相同的情况下,添加contentType。

See here for an explanation of the requirements to return JSON:

有关返回JSON的需求的解释,请参见这里:

ASMX and JSON – Common mistakes and misconceptions

ASMX和JSON——常见的错误和误解

The HTTP request must declare a content-type of application/json. This informs the ScriptService that it will receive its parameters as JSON and that it should respond in kind.

HTTP请求必须声明应用程序/json的内容类型。这将通知ScriptService,它将接收其作为JSON的参数,并以实物响应。

Now you still have another problem, and that is that the request, upon completion, calls the error function. If you change dataType: "jsonp" to dataType: "json" it will call the success function. So something about your implementation of the callback wrapper is wrong, because jQuery can't handle the response as JSONP.

现在您仍然有另一个问题,那就是请求在完成时调用error函数。如果您将dataType:“jsonp”更改为dataType:“json”,它将调用success函数。因此,对于回调包装器的实现有些问题是错误的,因为jQuery无法处理JSONP的响应。

Now I'm not seeing the callback wrapped in the response either, for JSONP, the response should be something like:

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

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

I notice you are linking to this post about how to do a JSONP response from a web service, but you are not following the advice: you don't use Response.Filter, instead you use Response.Write.

我注意到您正在链接这篇关于如何从web服务执行JSONP响应的文章,但是您没有遵循以下建议:不使用响应。而是使用Response.Write进行筛选。

#1


8  

It seems all the configuration and attributes are in place for the web service to return JSON but I did notice in your jQuery request, you are not specifying the content type of the data you are passing in. I have added it to the code below:

看起来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!");
  }
});

Notice I added contentType: "application/json; charset=utf-8", to the request settings.

注意,我添加了contentType:“application/json;到请求设置时,charset=utf-8。

I have tested this code by browsing to http://tonofweb.com (which returns a 403 at the moment), including jQuery using the jQuerify bookmarklet, and then running the code from your question first (without the contentType), and then the code I posted above (with the contentType).

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

Here are the responses from the Network tab in the Chrome Developer Tools:

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

Without contentType:

没有contentType:

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

With contentType:

contentType:

{"d":"12"}

So the second one at least results in JSON being returned from the server. So all else being equal, I'd say add the contentType.

因此第二个至少会导致从服务器返回JSON。在其他条件都相同的情况下,添加contentType。

See here for an explanation of the requirements to return JSON:

有关返回JSON的需求的解释,请参见这里:

ASMX and JSON – Common mistakes and misconceptions

ASMX和JSON——常见的错误和误解

The HTTP request must declare a content-type of application/json. This informs the ScriptService that it will receive its parameters as JSON and that it should respond in kind.

HTTP请求必须声明应用程序/json的内容类型。这将通知ScriptService,它将接收其作为JSON的参数,并以实物响应。

Now you still have another problem, and that is that the request, upon completion, calls the error function. If you change dataType: "jsonp" to dataType: "json" it will call the success function. So something about your implementation of the callback wrapper is wrong, because jQuery can't handle the response as JSONP.

现在您仍然有另一个问题,那就是请求在完成时调用error函数。如果您将dataType:“jsonp”更改为dataType:“json”,它将调用success函数。因此,对于回调包装器的实现有些问题是错误的,因为jQuery无法处理JSONP的响应。

Now I'm not seeing the callback wrapped in the response either, for JSONP, the response should be something like:

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

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

I notice you are linking to this post about how to do a JSONP response from a web service, but you are not following the advice: you don't use Response.Filter, instead you use Response.Write.

我注意到您正在链接这篇关于如何从web服务执行JSONP响应的文章,但是您没有遵循以下建议:不使用响应。而是使用Response.Write进行筛选。