【问题标题】:Requesting WCF Rest Service into JQGrid works with IE and not working with Chrome or Mozilla向 JQGrid 请求 WCF Rest 服务适用于 IE,但不适用于 Chrome 或 Mozilla
【发布时间】:2011-05-12 12:22:59
【问题描述】:

我使用 WCF Restful Services 作为我的业务层,当我尝试从 IE 9 中的服务“获取”数据时,它工作正常并填充 JQgrid,但是当我尝试使用 Chrome 或 Firefox 打开同一页面时我收到此错误消息。

{
    "statusText": "",
    "responseText": "",
    "response": "",
    "onabort": null,
    "readyState": 4,
    "upload": {
        "onloadstart": null,
        "onabort": null,
        "onerror": null,
        "onload": null,
        "onprogress": null
    },
    "onerror": null,
    "onreadystatechange": null,
    "status": 0,
    "responseXML": null,
    "onprogress": null,
    "onload": null,
    "withCredentials": false,
    "onloadstart": null,
    "responseType": ""
}

服务.svc

 [WebGet(UriTemplate = "LT_SectionListPage/?pageIndex={pageIndex}&pageSize={pageSize}&sortOrder={sortOrder}&sortColumn={sortColumn}", ResponseFormat = WebMessageFormat.Json)]  
    [OperationContract]

我使用 Fiddler2 进行追踪,这是 IE9 的输出

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Thu, 12 May 2011 11:53:40 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: application/json; charset=utf-8
Content-Length: 847
Connection: Close

和 Chrome 的输出

HTTP/1.1 405 Method Not Allowed
Server: ASP.NET Development Server/10.0.0.0
Date: Thu, 12 May 2011 11:54:07 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/html
Content-Length: 1137
Connection: Close

<html version="-//W3C//DTD XHTML 2.0//EN" xml:lang="en" xsi:schemaLocation="http://www.w3.org/1999/xhtml http:// www.w3.org/MarkUp/SCHEMA/xhtml2.xsd" xmlns="http:// www.w3.org/1999/xhtml" xmlns:xsi="http:// www.w3.org/2001/XMLSchema-instance"><HEAD><TITLE>Request Error</TITLE></HEAD><BODY><DIV id="content"><P class="heading1"><B>Error Description:</B> 'HTTP Method not allowed'</P><P><B>This may be because an invalid URI or HTTP method was specified. Please see the <A HREF="http:// localhost:1111/Rest.svc/help">service help page</A> for constructing valid requests to the service.</B></P><!-- Padding xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx--></DIV></BODY></html>

Chrome 中的请求

OPTIONS http:// localhost:1111/Rest.svc/LT_SectorListPage/json/?pageIndex=1&pageSize=100&sortOrder=asc&sortColumn=ID&_=1305207336766 HTTP/1.1
Host: localhost:1111
Connection: keep-alive
Referer: http:// localhost:1407/Default.aspx
Access-Control-Request-Method: GET
Origin: http:// localhost:1407
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.65 Safari/534.24
Access-Control-Request-Headers: X-Requested-With, Accept
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

在 IE9 中请求

GET http:// localhost:1111/Rest.svc/LT_SectorListPage/json/?pageIndex=1&pageSize=100&sortOrder=asc&sortColumn=ID&_=1305207423633 HTTP/1.1
x-requested-with: XMLHttpRequest
Accept-Language: ar-JO,en-US;q=0.5
Referer: http:// localhost:1407/Default.aspx
Accept: text/plain, */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Host: localhost:1111
Connection: Keep-Alive
Cookie: ASP.NET_SessionId=d212qpnffmvrzit1sx4z1mzb

Chrome 不接受该方法和 IE9,任何帮助将不胜感激。

谢谢

[更新提琴手状态]

将以下代码添加到 Global.asax 以处理 CORS 问题后

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            HttpContext.Current.Response.Cache.SetNoStore();
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                HttpContext.Current.Response.End();
            }
        }

请求

OPTIONS http:// localhost:1111/Rest.svc/LT_SectorListPage/json/?pageIndex=1&pageSize=100&sortOrder=asc&sortColumn=ID&_=1305213078870 HTTP/1.1
Host: localhost:1111
Connection: keep-alive
Referer: http:// localhost:1212/Default.aspx
Access-Control-Request-Method: GET
Origin: http:// localhost:1212
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.65 Safari/534.24
Access-Control-Request-Headers: X-Requested-With, Accept
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

回应

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0    
Date: Thu, 12 May 2011 15:11:18 GMT    
X-AspNet-Version: 2.0.50727    
Access-Control-Allow-Origin: *    
Access-Control-Allow-Methods: GET, POST    
Access-Control-Allow-Headers: Content-Type, Accept    
Cache-Control: no-cache, no-store    
Pragma: no-cache    
Expires: -1    
Content-Length: 0    
Connection: Close

【问题讨论】:

  • 我也不知道为什么 IE 中的 Content-Type 是 Content-Type: application/json 这是正确的,它返回的功能与 ontent-Type: text/html 在 Chrome 和 FireFox 中的功能相同跨度>
  • @user743863:您只包含了响应数据,没有包含 IE 和 Chrome 的请求数据。 chrome 中的错误HTTP Method not allowed 使得比较两种情况下的请求很有趣。您可以随时修改问题的文本并附加附加信息。此外,您的代码中有许多奇怪的东西:ExpandColumn: "menu" 并且没有名称为 "menu" 的列。 page: "CurretnPage"(不是当前的)。此外,jsonReader 中的名称不对应与您使用的 WebGet(UriTemplate ... 中的名称。
  • 嗨奥列格,我已经更新了这个问题,关于 jqgrid 这只是一个例子,我将从中删除这些参数
  • 我认为您应该将 WFC 服务放在同一个站点上并使用相对路径来解决它。我自己总是这样做,没有任何问题。例如,请参阅here

标签: jquery wcf rest jqgrid internet-explorer-9


【解决方案1】:

您遇到了跨域问题,因为您的服务托管在与客户端网页 (1407) 不同的端口 (1111) 上。因此,Chrome 正在发出 Cross Origin Resource Sharing Request (CORS),即 OPTIONS 请求,以在继续之前检查访问权限,您的服务目前显然不支持 CORS。

要解决此问题,您必须在 WCF 服务上实现对 CORS 请求的支持,或者在与网站相同的端口上运行 Web 服务。如果它们都将在生产环境中位于同一域/端口上,则没有理由花时间实施 CORS。

FWIW,在这种情况下,IE 在生产环境中也会失败。它之所以有效,是因为您正在访问 localhost,这将 IE 置于更宽松的 Intranet 安全策略中。

这里有更多关于 CORS 的文档/示例:

【讨论】:

  • 我试图维护跨域问题,我得到了 Response 200 OK 但没有像 IE9 那样返回数据,这里是监控的响应 HTTP/1.1 200 OK 服务器:ASP.NET Development Server/10.0.0.0日期:2011 年 5 月 12 日星期四 14:54:59 GMT X-AspNet-版本:2.0.50727 访问控制允许来源:* 访问控制允许方法:GET、POST 访问控制允许标头: Content-Type, Accept Cache-Control: no-cache, no-store Pragma: no-cache Expires: -1 Content-Length: 0 Connection: Close No data here :S
  • 这仍然是您向我展示的 CORS 响应。您是否真的将其更改为在一个端口上运行,或者您是否尝试实现 CORS 支持?请使用 fiddler 的完整请求/响应跟踪更新您的原始问题,以便我可以帮助进一步剖析。
  • 好的,你看到它是如何在 Access-Control-Request-Headers 中发送 X-Requested-With 的了吗?好吧,您只使用 Content-Type 和 Accept 的 Access-Control-Allow-Headers 进行响应。因此,预检请求无法发送它想要发送的标头,因此您的 GET 请求永远不会发出。如果您只想盲目地支持所有 CORS 请求,我建议您更改代码以仅回显请求的标头/方法。这是最简单的事情。不过,我不建议以这种方式进行生产。
  • 另外,另外一件事,我注意到您仅在 OPTIONS 请求时设置 CORS 标头,但您需要确保在 GET 响应中设置正确的 CORS 标头,否则不会工作。如果您发现此信息有用,如果投票和/或将其标记为答案,我将不胜感激。如果您仍然需要更多帮助,请让我知道您是否看到 GET 请求实际上已经通过。
  • 好吧,我真的很困惑,当我尝试将 GET 方法添加到 CORS 标头时,我得到了一个 json2 错误,老实说,我对整个想法感到困惑,你可以参考任何有用的文档来阅读,我肯定会在我解决这个问题后尽快标记你的答案,谢谢
【解决方案2】:

我用这个解决方法找到了这个问题的解决方案

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            //Enable Cross Domain WCF Configuration
            HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            HttpContext.Current.Response.Cache.SetNoStore();
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            string rqstMethod = HttpContext.Current.Request.Headers["Access-Control-Request-Method"];
            if (rqstMethod == "GET" || rqstMethod == "POST" || rqstMethod =="OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "3628800");
                HttpContext.Current.Response.AddHeader("type", "application/json; charset=utf-8");
                HttpContext.Current.Response.End();
            }
        }

您应该注意请求中接受的标头。

非常感谢@Drew Marsh 的帮助和有用的文档

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2013-05-03
    • 2016-09-25
    • 1970-01-01
    相关资源
    最近更新 更多