Header 没有为 OPTIONS Ajax 请求设置
Header not being set for OPTIONS Ajax request
我有一个 ascx
页面 GetToken.ashx
。
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
context.Response.Write(Token.CreateToken());
}
当我AJAX到这个页面时,它returns以下header:
Request Method:GET
Status Code:200 OK
Access-Control-Allow-Origin:*
Cache-Control:private
Content-Length:36
Content-Type:text/plain; charset=utf-8
Date:Tue, 14 Apr 2015 17:20:53 GMT
Server:Microsoft-IIS/8.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
当发出 AJAX 请求的页面被放置在沙盒 iFrame 中时,它显示错误:
XMLHttpRequest cannot load https://127.0.0.1:112/handlers/gettoken.ashx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
和returns headers:
Request Method:OPTIONS
Status Code:200 OK
Allow:OPTIONS, TRACE, GET, HEAD, POST
Content-Length:0
Date:Tue, 14 Apr 2015 17:30:14 GMT
Public:OPTIONS, TRACE, GET, HEAD, POST
Server:Microsoft-IIS/8.5
X-Powered-By:ASP.NET
我似乎无法获得添加 header 的 OPTIONS
请求。将 allow-same-origin
添加到沙盒属性会将请求更改为 GET
,但我不想授予 iFrame 这些权限。
确保您的 IIS 设置允许 OPTION
到该处理程序 - 部署到具有应用程序池名称 "web-app" 的应用程序并且相应的处理程序映射应该允许 OPTION
请求。
以下是执行此操作的步骤。
- select 需要应用程序池
- 单击处理程序映射
- select *.ashx 并双击相应的处理程序,单击 Request Restriction ,看看那里是否有选项动词,如果没有,请添加。
上面提到这里 - http://www.chrisweldon.net/blog/2012/04/13/jquery-file-uploader/
您可能需要使用以下代码。
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.AddHeader("Access-Control-Allow-Origin", "*");
// You can try adding requested origin here instead of * like this - Request.Headers["Origin"] or only the specific domain, in your case it is -https://127.0.0.1:112
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
context.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
context.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
context.Response.AddHeader("Access-Control-Max-Age", "1728000");
}
context.Response.Write(Token.CreateToken());
}
我已经在 my blog 中解释过了。这是针对 WCF 的,但它也应该适用于您的情况!您可能需要将 *
for allowed origin 更改为 requested origin,因为 * 存在安全问题,它允许所有域进行 CORS 调用。
您能否尝试在 您的 HTML 和 iFrame 页面(在 HTML DOC 中)添加以下代码并检查它是否有效?
<script>document.domain = 'myDomain.com'</script>
注意:请将 'myDomain' 替换为您正在使用的域的适当域名(来源)
如果没有 allow-same-origin
选项,从沙盒 iframe 发出 AJAX 请求似乎是绝对不可能的。
查看此答案以获得详细解释:IFRAME sandbox attribute is blocking AJAX calls
不过,我不太相信。在放弃之前,请确保您的服务器接受 AJAX 来自不同主机名的请求而无需沙盒(即,如果它支持 CORS)。
有关 CORS 的更多信息,请参阅:http://www.html5rocks.com/en/tutorials/cors/
我假设您打算写 ashx
,而不是 ascx
。 ProcessRequest (HttpContext context)
方法的存在表明它是通用处理程序而不是用户控件。
我制作了一个非常简单的页面来测试:
<%@ Page Language="C#" AutoEventWireup="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="Scripts/jquery-1.4.1.js"></script>
</head>
<body>
<div id="testCorsDiv">
</div>
<script type="text/javascript">
$.ajax({
type: "GET",
url: "/Handler/testCors.ashx",
dataType: "text",
success: function (theData) { $("#testCorsDiv").text(theData); },
error: function (theData) { alert('error'); }
});
</script>
<% if(string.IsNullOrEmpty(Request.QueryString["sandboxed"])) { %>
<iframe src="http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true" sandbox="allow-scripts" width="600">
</iframe>
<% } %>
</body>
</html>
我在 http://localhost:49253/SandboxTest.aspx
加载页面。该页面然后向 http://localhost:49253/Handler/testCors.ashx
发出 ajax
请求并将其输出放入 testCorsDiv
div。这会直接向处理程序生成 GET
(因为它来自同一来源)并插入输出。
页面中还有一个沙盒 iframe
,它使用 url http://127.0.0.1:49253/SandboxTest.aspx
加载同一页面。 ?sandboxed=true
用于防止 iframe 递归加载内部 iframe。然后,加载到 iframe 中的页面将尝试向 http://127.0.0.1:49253/Handler/testCors.ashx
发出 ajax 请求,并在它自己的 testCorsDiv
div.
副本中显示输出
只要沙盒 iframe 有 allow-scripts
,这就很有魅力了。 iframe
生成如下所示的 OPTIONS
请求(来自 Fiddler,使用 Chrome 测试):
OPTIONS http://127.0.0.1:49253/Handler/testCors.ashx HTTP/1.1
Host: 127.0.0.1:49253
Connection: keep-alive
Cache-Control: max-age=0
Access-Control-Request-Method: GET
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36
Access-Control-Request-Headers: accept, x-requested-with
Accept: */*
Referer: http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true
Accept-Encoding: gzip, deflate, sdch
Accept-Language: fi-FI,fi;q=0.8,en-US;q=0.6,en;q=0.4
我的 testCors.ashx
处理程序然后吐出一些 headers 说这看起来 ay-ok 然后浏览器跟进 GET
并且它正常工作。
testCors.ashx
这样做:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
context.Response.AppendHeader("Access-Control-Allow-Headers", "content-type, x-requested-with, accept");
context.Response.AppendHeader("Access-Control-Allow-Methods", "POST, OPTIONS, GET");
context.Response.Write("Hello World");
}
所以我的测试表明应该可以做你想做的事。尽管这可能是一个问题,但如果您的处理程序只能由 authenticated/authorized 用户访问。如您所见,OPTIONS
请求尚未向处理程序发送 cookie。但另一方面,您的问题表明对您的选项请求的响应是 Status Code:200
。我想如果缺少必需的身份验证 cookie,那将是一些 4**
。
总结一下,我真的不知道你的情况出了什么问题,但也许(?)我的简单示例页面可以给你一些线索,帮助你自己找到问题。
您遇到的错误:
XMLHttpRequest cannot load https://127.0.0.1:112/handlers/gettoken.ashx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
是因为您的应用程序已免受点击劫持攻击。在您的情况下,您的应用程序 web.config 中的 X-Fame-Options
可能设置为 Deny
,将其设置为 'SAMEORIGIN' 将有助于解决您的问题,前提是您的应用程序具有与你的 iframe
.
这是这样做的:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
</system.webServer>
如果你能找到解决这个问题的方法(我的意思是让你的应用程序在设置了拒绝选项的 iframe 中工作),那么它会破坏拥有这样一个功能的唯一目的(防止点击劫持的安全性)。
希望对您有所帮助。
我有一个 ascx
页面 GetToken.ashx
。
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
context.Response.Write(Token.CreateToken());
}
当我AJAX到这个页面时,它returns以下header:
Request Method:GET
Status Code:200 OK
Access-Control-Allow-Origin:*
Cache-Control:private
Content-Length:36
Content-Type:text/plain; charset=utf-8
Date:Tue, 14 Apr 2015 17:20:53 GMT
Server:Microsoft-IIS/8.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
当发出 AJAX 请求的页面被放置在沙盒 iFrame 中时,它显示错误:
XMLHttpRequest cannot load https://127.0.0.1:112/handlers/gettoken.ashx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
和returns headers:
Request Method:OPTIONS
Status Code:200 OK
Allow:OPTIONS, TRACE, GET, HEAD, POST
Content-Length:0
Date:Tue, 14 Apr 2015 17:30:14 GMT
Public:OPTIONS, TRACE, GET, HEAD, POST
Server:Microsoft-IIS/8.5
X-Powered-By:ASP.NET
我似乎无法获得添加 header 的 OPTIONS
请求。将 allow-same-origin
添加到沙盒属性会将请求更改为 GET
,但我不想授予 iFrame 这些权限。
确保您的 IIS 设置允许 OPTION
到该处理程序 - 部署到具有应用程序池名称 "web-app" 的应用程序并且相应的处理程序映射应该允许 OPTION
请求。
以下是执行此操作的步骤。
- select 需要应用程序池
- 单击处理程序映射
- select *.ashx 并双击相应的处理程序,单击 Request Restriction ,看看那里是否有选项动词,如果没有,请添加。
上面提到这里 - http://www.chrisweldon.net/blog/2012/04/13/jquery-file-uploader/
您可能需要使用以下代码。
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.AddHeader("Access-Control-Allow-Origin", "*");
// You can try adding requested origin here instead of * like this - Request.Headers["Origin"] or only the specific domain, in your case it is -https://127.0.0.1:112
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
context.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
context.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
context.Response.AddHeader("Access-Control-Max-Age", "1728000");
}
context.Response.Write(Token.CreateToken());
}
我已经在 my blog 中解释过了。这是针对 WCF 的,但它也应该适用于您的情况!您可能需要将 *
for allowed origin 更改为 requested origin,因为 * 存在安全问题,它允许所有域进行 CORS 调用。
您能否尝试在 您的 HTML 和 iFrame 页面(在 HTML DOC 中)添加以下代码并检查它是否有效?
<script>document.domain = 'myDomain.com'</script>
注意:请将 'myDomain' 替换为您正在使用的域的适当域名(来源)
如果没有 allow-same-origin
选项,从沙盒 iframe 发出 AJAX 请求似乎是绝对不可能的。
查看此答案以获得详细解释:IFRAME sandbox attribute is blocking AJAX calls
不过,我不太相信。在放弃之前,请确保您的服务器接受 AJAX 来自不同主机名的请求而无需沙盒(即,如果它支持 CORS)。
有关 CORS 的更多信息,请参阅:http://www.html5rocks.com/en/tutorials/cors/
我假设您打算写 ashx
,而不是 ascx
。 ProcessRequest (HttpContext context)
方法的存在表明它是通用处理程序而不是用户控件。
我制作了一个非常简单的页面来测试:
<%@ Page Language="C#" AutoEventWireup="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="Scripts/jquery-1.4.1.js"></script>
</head>
<body>
<div id="testCorsDiv">
</div>
<script type="text/javascript">
$.ajax({
type: "GET",
url: "/Handler/testCors.ashx",
dataType: "text",
success: function (theData) { $("#testCorsDiv").text(theData); },
error: function (theData) { alert('error'); }
});
</script>
<% if(string.IsNullOrEmpty(Request.QueryString["sandboxed"])) { %>
<iframe src="http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true" sandbox="allow-scripts" width="600">
</iframe>
<% } %>
</body>
</html>
我在 http://localhost:49253/SandboxTest.aspx
加载页面。该页面然后向 http://localhost:49253/Handler/testCors.ashx
发出 ajax
请求并将其输出放入 testCorsDiv
div。这会直接向处理程序生成 GET
(因为它来自同一来源)并插入输出。
页面中还有一个沙盒 iframe
,它使用 url http://127.0.0.1:49253/SandboxTest.aspx
加载同一页面。 ?sandboxed=true
用于防止 iframe 递归加载内部 iframe。然后,加载到 iframe 中的页面将尝试向 http://127.0.0.1:49253/Handler/testCors.ashx
发出 ajax 请求,并在它自己的 testCorsDiv
div.
只要沙盒 iframe 有 allow-scripts
,这就很有魅力了。 iframe
生成如下所示的 OPTIONS
请求(来自 Fiddler,使用 Chrome 测试):
OPTIONS http://127.0.0.1:49253/Handler/testCors.ashx HTTP/1.1
Host: 127.0.0.1:49253
Connection: keep-alive
Cache-Control: max-age=0
Access-Control-Request-Method: GET
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36
Access-Control-Request-Headers: accept, x-requested-with
Accept: */*
Referer: http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true
Accept-Encoding: gzip, deflate, sdch
Accept-Language: fi-FI,fi;q=0.8,en-US;q=0.6,en;q=0.4
我的 testCors.ashx
处理程序然后吐出一些 headers 说这看起来 ay-ok 然后浏览器跟进 GET
并且它正常工作。
testCors.ashx
这样做:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
context.Response.AppendHeader("Access-Control-Allow-Headers", "content-type, x-requested-with, accept");
context.Response.AppendHeader("Access-Control-Allow-Methods", "POST, OPTIONS, GET");
context.Response.Write("Hello World");
}
所以我的测试表明应该可以做你想做的事。尽管这可能是一个问题,但如果您的处理程序只能由 authenticated/authorized 用户访问。如您所见,OPTIONS
请求尚未向处理程序发送 cookie。但另一方面,您的问题表明对您的选项请求的响应是 Status Code:200
。我想如果缺少必需的身份验证 cookie,那将是一些 4**
。
总结一下,我真的不知道你的情况出了什么问题,但也许(?)我的简单示例页面可以给你一些线索,帮助你自己找到问题。
您遇到的错误:
XMLHttpRequest cannot load https://127.0.0.1:112/handlers/gettoken.ashx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
是因为您的应用程序已免受点击劫持攻击。在您的情况下,您的应用程序 web.config 中的 X-Fame-Options
可能设置为 Deny
,将其设置为 'SAMEORIGIN' 将有助于解决您的问题,前提是您的应用程序具有与你的 iframe
.
这是这样做的:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
</system.webServer>
如果你能找到解决这个问题的方法(我的意思是让你的应用程序在设置了拒绝选项的 iframe 中工作),那么它会破坏拥有这样一个功能的唯一目的(防止点击劫持的安全性)。
希望对您有所帮助。