无法POST到IHTTPHandler类,Access-Control-Allow-Origin不允许原点
我有一个C#SOAP Web服务以及部署到https://localhost:123
一些自定义IHTTPHandler
类。 我在http://localhost
上有一个HTML页面,试图使用jQuery向其中一个处理程序发送一个AJAX POST请求。 我每次都得到以下内容:
XMLHttpRequest无法加载
https://localhost:123/(S(the_session_id))/MyHandler.ashx
。 Access-Control-Allow-Origin不允许使用originhttp://localhost
。
我试过像这个问题一样创建一个CrossOriginModule
模块和CrossOriginHandler
处理程序,按照他们的建议更新我的web.config。 我尝试添加了context.Response.AppendHeader("Access-Control-Allow-Headers", "x-requested-with");
我的处理程序的ProcessRequest
,正如这个问题所示 。 我尝试按照本博客文章中的步骤,在Web.config中的system.webServer
/ handlers
中将OPTIONS
添加到SimpleHandlerFactory-Integrated-4.0
。 什么都没有帮助。
这是我的处理程序的ProcessRequest
:
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/json"; context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); context.Response.AppendHeader("Access-Control-Allow-Headers", "x-requested-with"); context.Response.Write( /* some JSON string */ ); }
这是我的web.config的相关部分:
使用jQuery 1.7.2,这是我向处理程序发出请求的方式:
$.ajax({ url: url, data: {user: userName, pass: password}, type: 'POST', dataType: 'json', success: function(data, textStatus, jqXHR) { ... } });
我也没有在服务器上使用cookie进行会话,所以在我的web.config中,如果这很重要的话。 我的服务器是IIS 7.5。
我能够为大多数请求使用JSONP,因为我没有在URL中传递敏感数据。 但是,对于这个处理程序,我需要进行常规POST,因为它涉及发送纯文本密码。 这是通过SSL,但是这篇文章建议不要通过SSL传递URL中的敏感数据。 因此,我需要通过AJAX对https URL执行POST请求并返回JSON,并且请求页面不会与服务器位于同一主机上。
编辑:我尝试过的其他一些事情:
更改我的web.config httpProtocol
部分:
我添加了context.Response.AppendHeader("Access-Control-Allow-Methods", "POST");
到ProcessRequest
。 我也尝试了context.Response.AppendHeader("Access-Control-Allow-Methods", "POST,OPTIONS");
并更改我的jQuery ajax
选项以包含contentType: 'application/json'
,这会导致它发出OPTIONS请求而不是POST – 这仍然失败。
我应该在列出web.config中的所有自定义
IHTTPHandler
类吗? 我现在有MyHandler
,其verb="*"
,但它似乎没有帮助。
编辑:所以有些进一步的陌生感。 根据我的日志记录输出,看起来我的请求实际上是在服务器端进行的,但是浏览器的行为就像它被拒绝了,仍然告诉我’origin localhost不允许’。 所以我对服务器的AJAX POST就像我希望的那样对我进行身份validation,但是浏览器取消了请求并且Chrome控制台中显示错误,因此我的success
事件处理程序不会触发。
您的处理程序的ProcessRequest还应设置以下标头:
Access-Control-Allow-Methods: POST
(基本上,应在OPTIONS响应中设置此标头,以及Access-Control-Allow-Headers响应标头)。
这是愚蠢的,我不知道发生了什么,但我的POST正在进行,我的身份validation发生在服务器上,但浏览器认为这是不允许的,所以它失败了。 我已经有一个支持JSONP的处理程序,它将告诉会话是否仍处于活动状态并且用户已经过身份validation,因此我将AJAX调用更改为以下内容:
$.ajax({ url: url, data: {user: userName, pass: password}, type: 'POST', dataType: 'json', complete: function(jqXHR, textStatus) { checkIfAuthenticated( function() { // authenticated onComplete(true, null) }, function() { // not authenticated onComplete(false, textStatus); } ); } });
所以我仍然有一个“XMLHttpRequest无法加载https://.../AuthHandler.ashx
。来自我的Chrome控制台和网络中出现的Access-Control-Allow-Origin不允许发送http://localhost
”错误Chrome中的标签仍然会将POST请求显示为已取消。 我最终必须通过checkIfAuthenticated
函数在此处发出额外请求,以查看身份validation是否失败,但它可以正常工作。
我在MyHandler
服务器上的ProcessRequest
如下所示:
public void ProcessRequest(HttpContext context) { context.Response.ClearHeaders(); string origin = context.Request.Headers["Origin"]; context.Response.AppendHeader("Access-Control-Allow-Origin", string.IsNullOrEmpty(origin) ? "*" : origin); string requestHeaders = context.Request.Headers["Access-Control-Request-Headers"]; context.Response.AppendHeader("Access-Control-Allow-Headers", string.IsNullOrEmpty(requestHeaders) ? "*" : requestHeaders); context.Response.AppendHeader("Access-Control-Allow-Methods", "POST, OPTIONS"); context.Response.ContentType = "application/json"; context.Response.Write(/* JSON response */); context.Response.Flush(); }
这就是我的web.config的相关部分最终看起来像:
我更倾向于使用我的浏览器说服该请求确实被允许的解决方案,因为这是一个愚蠢的解决方法。