使用 jQuery/Ajax 从 JavaScript 调用 WCF/JSON/REST WebService

Posted

技术标签:

【中文标题】使用 jQuery/Ajax 从 JavaScript 调用 WCF/JSON/REST WebService【英文标题】:Calling WCF/JSON/REST WebService from JavaScript using jQuery/Ajax 【发布时间】:2011-09-06 11:14:39 【问题描述】:

我知道有很多关于此的问题 - 相信我,我已经阅读了很多问题并尝试了答案。

(这个项目是针对公司内部局域网的,不是互联网)

我们有一个 WCF Web 服务,它是 RESTFUL 并发送/接收 JSON,它需要 NTLM(Kerb 也很好)身份验证/凭据以确保调用用户(来自浏览器的用户就是他们所说的),并且这个通过 WCF 绑定在浏览器/客户端和服务之间协商:

 <bindings>
  <webHttpBinding>
    <binding name="webHttpBindingAuth">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Ntlm"/>
      </security>
    </binding>
  </webHttpBinding>
</bindings>

使用 Fiddler,我可以成功调用服务 GET 和 POST 上的方法,并且只要我调整了我们发送到 Web 服务的 JSON(例如包括会话 ID),它就会愉快地运行。

问题开始于我们尝试使用 javascript/jQuery 调用 web 服务时;这个想法是 Web 服务器将 html/JS 提供给客户端浏览器,然后浏览器应该调用 WCF Web 服务来获取会话并允许用户执行一些操作(我们总共有 3 个方法)。

首先,我们遇到了 X 域问题,我们试图通过让 Web 服务器 返回正确的标头 (Access-Control-Allow-Origin) 来解决该问题。这并没有阻止像 SRIron 这样的浏览器告诉我们这一点;

XMLHttpRequest cannot load http://webServiceUri/InstantMessagingService/chat/start/username. Origin http://web**Server**Uri is not allowed by Access-Control-Allow-Origin.

在此之后,我调查了使用 Silverlight 的可能性(似乎不支持通过 WebHttpBinding 进行 NTLM 身份验证),反向代理不可用,因为在 dev 中使用的 IIS 服务器不会在 prod 中使用(我 相信它是WebSphere,但不受我们控制);接下来我看了这个:

http://msmvps.com/blogs/paulomorgado/archive/2007/04/27/wcf-building-an-http-user-agent-message-inspector.aspx

这让我觉得 WCF Web 服务实际上是需要告诉浏览器允许从哪里调用它的东西(如果这有意义的话)。实现了示例中的所有代码后,我发现从未调用 ApplyClientBehavior 来尝试将标头返回给客户端(也在 Fiddler 中对此进行监控)。更多谷歌搜索导致我:

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/707aa031-f4ff-47ab-ba5b-730f7930605e/

由于我们使用 jQuery 而不是某些 .NET 客户端/服务参考/代理/应用程序来访问 Web 服务,所以我认为不可能预先请求发送这些标头以允许访问服务。此外,Fiddler 似乎认为它在尝试调用 http://../chat/start/.. 方法时得到了 401 Unauthorized。

这是我用来尝试调用的 jQuery(我提供了一些设置,希望它能正常工作):

var url = webserviceUrl + "chat/start/" + remoteUserUri;

$.ajax(
    type: 'GET',   
    url: url,
    crossDomain: true,
    beforeSend: function(xhr) xhr.withCredentials = true; ,
    contentType: "application/json; charset=utf-8",               
    success: function (data)  conversationStarted(data); ,
    dataType: 'json'
); 

好的,如果有人有有用的提示或想法,请开火。我会回复和编辑等,以确保这是最新的,我希望我没有错过任何东西(但是我的谷歌搜索让我头晕目眩)。

另外,我知道可能有更好的方法来做到这一点,但我想以我现在最干净/最快的方式来做到这一点 - 即不需要很多代码更改、重写等。我可以如果人们认为它们真的有用,也可以发布配置。

【问题讨论】:

【参考方案1】:

最后我不得不解决一些问题,我们让负责 Web 服务器的人同意提供一个 IFrame,该 IFrame 指向我们的 IIS 托管页面(包含 JS 等的页面)

然后使用 WCF/Windows 的魔力,我们在端口 80 上托管 WCF 服务,从而绕过 X-Domain 起源的东西。这样我就可以拥有 REST/JSON 而无需使用 JSONP。

根据我指定的标准,我知道这不是问题的答案,但我认为我最终完全没有选择。

【讨论】:

【参考方案2】:

你可以使用 JSONP 吗?瞬间解决你的跨域问题。

【讨论】:

不,他不能,但我忘记了原因(整天和他一起看着这个)。与 Jsonp 可以处理 GET 方法请求有关,但不能处理 POST ? 正如 GodEater 所说,JSONP 无法进行 POST,所以似乎不行:***.com/questions/5345493/…

以上是关于使用 jQuery/Ajax 从 JavaScript 调用 WCF/JSON/REST WebService的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 不会从 AJAX 查询中解析我的 JSON

使用 Jquery、AJAX 和 PHP 从 MySQL 数据库中检索数据

如何使用 JQuery.ajax 从每个 WordPress 帖子中获取缩略图附件?

如何使用 jQuery 和 ASP.NET MVC 从 AJAX 调用返回错误消息?

使用 jquery .ajax 从 mySQL DB 中检索记录

从 PHP (jQuery/AJAX) 插入 MySQL