`

jquery跨域调用webService

 
阅读更多

jquery跨域调用webService,以及解决跨域情况下只能返回XMl格式数据的问题

http://lu.9efish.com/blog/jquery-cross-domain-call-asp.net-web-service原文地址

网上有很多文章介绍如何使用jquery调用web service,在同一个域里都没什么问题 运行都是良好的。但在实际的应用中 我们既然已经部署了web
service当然是希望有更多的外部的客户端调用的。而其中就有其他域里的javascript调用web service获取信息的需求。

在网上找了一下 也是有文章介绍的 文章1 文章2 我的解决思路基本上就是从这两篇文章里来的。但使用这两篇文章的时候也碰到了一点问题
所以我使用自己的方式修改了一下。jquery跨域调用asp.net web service,首先要了解的一个概念是 JSONP 链接里有介绍。

总之为了安全 少些网络攻击 钓鱼等,跨域访问是要受到严格限制的。比如
不能跨域使用POST,JQuery调用也需要使用JSONP来传输数据。但由于asp.net 3.5的web
service不内置支持jsonp,碰上很多问题。下面列出我已经测试正确的方法。

首先看客户端JQuery的代码:

-------------------------------------------------------------------------------------------------------------------

<script type="text/javascript">
    $(function () {
        $.ajax({
            url: 'http://myserver/Web%20Service/Search.asmx/Search?format=jsonp',
            data: {'from': 'Oslo', 'to': 'Hamburg', 'type': 1 },
            dataType: "jsonp",
            type: "GET",
            success: OnSuccess,
            error: OnError
        });
    });
 
    function OnSuccess(jsondata) {
    }
    function OnError (xhr, msg){ 
    }
</script>

------------------------------------------------------------------------------------------------------------------

代码里Jquery ajax的调用使用的type为 "GET",
所以就算在这里指定了contentType也是没有用的,这就是悲剧的源头。上面的代码里要注意的一个地方是在调用的URL里我们添加了一个参数format=jsonp,
这个后面会使用到。然后再是web service的代码:

----------------------------------------------------------------------------------------------------------------

[WebService(Namespace = "http://temp.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class Search : System.Web.Services.WebService {
 [WebMethod(EnableSession=true)]
 [ScriptMethod(ResponseFormat = ResponseFormat.Json,UseHttpGet=true)]
 public string Search(string from,string to,int type) {
   SearchResult result= new SearchResult();
......
 return result.toJSON(); }}

-------------------------------------------------------------------------------------------------------------------

根据上面的代码 再在web.config里加上下面一句话

------------------------------------------------------------------------------------------------------------------

<system.web>   
.......
    <webServices>
      <protocols>
        <addname="HttpGet"/>
        <addname="HttpPost"/>
      </protocols>
    </webServices>
</system.web>

-----------------------------------------------------------------------------------------------------------------

到这里 如果你跟踪代码执行的话 其实web service的代码调用已经是成功了的,但你是得不到返回值的,如果用firebug查看一下
会有一个错误出现,是jquery解析返回值的时候出错的信息。问题是这样出现的 在web service返回值时 其实没有返回JSONP格式
而是把你生成的string返回值包到了一个xml格式里。在上面提到的两篇文章里
作者都使用了一个HttpModule来拦截Request请求,强制给Request.ContentType赋值为"application/json;
charset=utf-8", 这样web service返回值也是使用json格式返回 然后再在HttpModule包上一个JSONP的外衣也算是大功告成。
但我在实际使用时碰上了一个问题,就是当Request.ContentType="application/json; charset=utf-8"
后,解析我Jquery里Data的参数出现了错误,而上面的文章里也是使用了对URL参数进行进一步的包装之后 才让asp.net web
service解析成功。而我为了使客户端精良的简单使用了另外一个办法就是在web service返回的xml格式的结果时
进行重新包装。当然也是需要添加一个IHttpModule的 代码可以在这里下载

通过这样的改造 jquery就能正确解析出结果了。下面再给出那个.toJSON的代码

-----------------------------------------------------------------------------------------------------------------

public static class Extention
{
    public static string toJSON(this object obj)
    {
        string jsonstring = new JavaScriptSerializer().Serialize(obj);
        return jsonstring;
    }
}

-----------------------------------------------------------------------------------------------------------------

以上代码 实际能用IE8,firefox测试

==================================================================================

 

下面加个demo:

js:

复制代码
    <script src="../js/jquery-1.6.4.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(function() {
            $.ajax({
                type: "GET",
                cache: false,
                url: "http://localhost:7067/WebService/Service.asmx/GetJsonp?format=jsonp",
                //url: "../WebService1.asmx/GetJsonp",                data: { value: 'GET 参数', secretCode: '111111111' },
                dataType: "jsonp",
                jsonp: "callback",
                jsonpCallback: "showRs"
            });


        });
        function showRs(_rs) {
            alert(_rs.msg);
        }
    </script>
复制代码

WS:

复制代码
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
    public string GetJsonp(string value, string secretCode)
    {
        string jsonpcallback = HttpContext.Current.Request.QueryString["callback"];
        return "{\"msg\":\"" + value + secretCode + "\"}";
        //return jsonpcallback + "('" + value + secretCode + "')";    }
复制代码


下面是那个Module代码,以防链接失效:

View Code
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Text;
using System.Xml.Linq;
///<summary>/// 解决ajax跨域调用web service返回结果需要修改
/// web service不认jsonp的格式 会自动返回xml 使客户端 如jquery等解析出错
///</summary>public class JsonpHttpModule : IHttpModule
{
    private const string JSON_CONTENT_TYPE = "application/json; charset=utf-8";

    #region IHttpModule Members
    public void Dispose()
    {
    }

    public void Init(HttpApplication app)
    {
        app.BeginRequest += OnBeginRequest;
        app.ReleaseRequestState += OnReleaseRequestState;
    }
    #endregion
    bool _Apply(HttpRequest request)
    {
        if (!request.Url.AbsolutePath.Contains(".asmx")) return false;
        if ("jsonp" != request.QueryString.Get("format")) return false;
        return true;
    }

    public void OnBeginRequest(object sender, EventArgs e)
    {
        //HttpApplication app = (HttpApplication)sender;

        //if (!_Apply(app.Context.Request)) return;
        //// correct content type of request        //if (string.IsNullOrEmpty(app.Context.Request.ContentType))
        //{
        //    app.Context.Request.ContentType = JSON_CONTENT_TYPE;
        //}
    }

    public void OnReleaseRequestState(object sender, EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;
        if (!_Apply(app.Context.Request)) return;
        // apply response filter to conform to JSONP
        //由于使用Http Get 默认的解析方法 在返回内容是会使用xml格式 这里把他的xml外衣脱掉        app.Context.Response.Filter =
            new JsonResponseFilter(app.Context.Response.Filter);

    }
}

public class JsonResponseFilter : Stream
{
    private readonly Stream _responseStream;
    private long _position;

    public JsonResponseFilter(Stream responseStream)
    {
        _responseStream = responseStream;
    }

    public override bool CanRead { get { return true; } }

    public override bool CanSeek { get { return true; } }

    public override bool CanWrite { get { return true; } }

    public override long Length { get { return 0; } }

    public override long Position { get { return _position; } set { _position = value; } }

    public override void Write(byte[] buffer, int offset, int count)
    {
        string strBuffer = Encoding.UTF8.GetString(buffer, offset, count);
        strBuffer = AppendJsonpCallback(strBuffer, HttpContext.Current.Request);
        byte[] data = Encoding.UTF8.GetBytes(strBuffer);
        _responseStream.Write(data, 0, data.Length);
    }

    private string AppendJsonpCallback(string strBuffer, HttpRequest request)
    {
        try
        {
            XDocument x = XDocument.Parse(strBuffer);
            return request.Params["callback"] + "(" + x.Descendants ().FirstOrDefault ().Value + ");";
        }
        catch
        {
            return strBuffer;
        }
    }

    public override void Close()
    {
        _responseStream.Close();
    }

    public override void Flush()
    {
        _responseStream.Flush();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return _responseStream.Seek(offset, origin);
    }

    public override void SetLength(long length)
    {
        _responseStream.SetLength(length);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _responseStream.Read(buffer, offset, count);
    }
}
复制代码
 
参考:
http://www.codeproject.com/Articles/43038/Accessing-Remote-ASP-NET-Web-Services-Using-JSONP
分享到:
评论

相关推荐

    jquery跨域调用webservice

    本文将详细解释如何利用jQuery通过JSONP(JSON with Padding)的方式实现跨域调用WebService。 #### 1. JSONP 的基本原理 JSONP 是一种解决跨域请求的有效手段,它通过动态创建`&lt;script&gt;`标签来请求跨域的数据,并...

    Jquery调用WebService示例方法(源代码)

    本示例将深入探讨如何使用jQuery来调用WebService,通过源代码解析相关知识点。 首先,了解jQuery的核心功能对理解jQuery调用WebService至关重要。jQuery提供了`$.ajax()`函数,它是进行异步数据请求的基础。在这个...

    jquery调用Webservice的demo(.net)

    本教程将通过一个简单的示例来讲解如何使用jQuery调用.NET环境下的ASMX Web服务。 一、jQuery与Web服务基础 1. jQuery:jQuery简化了JavaScript的API,提供了一致的跨浏览器接口,使得开发者可以更方便地处理DOM...

    js跨域调用WebService的简单实例

    标题:“js跨域调用WebService的简单实例”主要探讨了如何在JavaScript中进行跨域调用WebService的问题,并提供了一个具体的实现示例。这个知识点是在Web开发中常见的问题,当前端JavaScript需要与后端进行数据交互...

    ajax跨域请求调用webservice接口+视频教程

    【标题】"Ajax跨域请求调用WebService接口"是一个关键的技术点,主要涉及到Web开发中的异步数据交互和跨域安全策略。在Web应用程序中,Ajax(Asynchronous JavaScript and XML)技术允许我们在不刷新整个页面的情况...

    ajax跨域调用webservice的实现代码

    标题中的“ajax跨域调用webservice的实现代码”指的是使用AJAX技术在JavaScript中跨域请求Web服务(webservice)的方法。AJAX允许在不刷新整个页面的情况下与服务器进行异步通信,而Web服务则提供了接口供客户端应用...

    jQuery调用 WebService的实现代码

    在本文中,我们将深入探讨如何使用jQuery来调用WebService,这是一种常见的前端与后端交互方式。jQuery是一个轻量级的JavaScript库,它简化了HTML文档遍历、事件处理、动画和Ajax交互,使得Web开发更加高效。而...

    Jquery Ajax 跨域调用asmx类型 WebService范例代码

    摘要:Ajax 在 Web 2.0 时代起...本文以asmx方式搭建webservice作为测试用后端,给出完整的前后端调用解决方案、范例代码。 本资源为代码部分。 博文请见:http://blog.csdn.net/fanrong1985/article/details/51345436

    ajax跨域请求WebService.asmx

    5. **调用方法**:在客户端,使用jQuery或者其他JavaScript库(如axios或fetch)的Ajax方法来调用WebService.asmx中的方法。需要指定URL、请求类型、数据格式(JSON或XML)等参数,并在回调函数中处理返回的结果。 ...

    一个基于jquery调用WebService和WebService输出JSON的源码例子

    调用WebService时要考虑跨域问题,可能需要启用服务器端的CORS(跨源资源共享)。同时,优化Ajax请求,如使用缓存、设置超时等,可以提高性能和用户体验。 7. 开发工具与调试: 使用浏览器的开发者工具(如Chrome...

    jQuery使用Ajax方法调用WebService

    本文将深入探讨如何使用jQuery的Ajax方法来调用WebService,从而实现异步数据交换,提升用户体验。 首先,理解Ajax(Asynchronous JavaScript and XML)的核心概念是关键。Ajax允许网页在不刷新整个页面的情况下与...

    JQuery调用WebService

    但通过JSONP或CORS(跨源资源共享)机制,可以实现跨域调用WebService。 ### 9. 文件`JqueryData`的使用 文件`JqueryData`可能是用来存储示例数据或者用于模拟Web服务响应的JSON数据。在实际应用中,`$.ajax()`的`...

    js调用webService组件

    综上所述,JavaScript调用WebService涉及到的主要知识点包括:XMLHttpRequest对象的使用、SOAP消息的构造、跨域请求的处理以及响应数据的解析和处理。在实际项目中,理解这些概念和技术将有助于你更有效地实现客户端...

    js跨域调用

    在本实例中,我们将讨论如何使用JS实现跨域调用WebService。"JqCrossDomain"这个文件名可能指的是使用jQuery库来处理跨域请求,因为jQuery提供了一些方便的方法来简化这个过程。 首先,了解同源策略是理解跨域调用...

    Jquery调用Webservice

    JSONP跨域调用** Web服务常常部署在不同的域名下,浏览器的同源策略会限制前端直接发起跨域请求。为解决这个问题,jQuery支持JSONP(JSON with Padding)模式,通过动态创建`&lt;script&gt;`标签来规避同源策略。 ```...

    js调用webservice示例+源码

    本文将深入探讨如何使用JavaScript调用Web Service,以及如何解决在这个过程中遇到的问题,以配合“js调用webservice示例+源码”的主题。 Web Service是一种基于网络的、平台无关的服务,它通过SOAP(Simple Object...

    使用JavaScript调用WebService的示例

    本篇将深入探讨如何使用JavaScript调用WebService,帮助开发者理解和掌握这一技术。 首先,了解WebService的基本概念。WebService是一种基于开放标准(如XML、SOAP、WSDL和UDDI)的应用程序接口(API),允许不同...

    jQuery ajax调用webservice注意事项

    在使用jQuery AJAX调用Web Service时,需要注意一些关键点以确保功能正常运行并避免常见问题。以下是关于这个主题的一些详细说明: 1. **配置Web.config**: 在Web应用程序的Web.config文件中,你需要配置HTTP...

    JS调用WEBSERVICE的demo

    在这个"JS调用WEBSERVICE的demo"中,我们将会探讨如何使用JavaScript来调用Web Service,以及相关的技术要点。 首先,让我们理解什么是Web Service。Web Service是一种基于网络的、可互操作的软件接口,它能够通过...

Global site tag (gtag.js) - Google Analytics