一个站点上没有 'Access-Control-Allow-Origin' header,但另一个站点上没有
No 'Access-Control-Allow-Origin' header on one site, but not on another
我们有一个系统,由一个用 ASP.NET/MVC 编写的网站和一个用 ASP.NET/WEBAPI 编写的网络服务站点组成。用户从网站加载页面,使用 JQuery.
调用 Web 服务站点 AJAX
我们正在使用 VS2013 构建它,并使用 MS 的 Web 部署对其进行部署,运行 来自 Jenkins 中配置的作业,因此在 fumble-finger 期间,人们没有太多机会进行某些操作安装。
我们的问题 - 当我们将这两个站点部署到我们的 QA 环境时,一切正常。我们可以访问 Web 服务并加载页面,他们对 Web 服务进行 AJAX 调用,Bob 是你的叔叔。
但是当我们将这两个站点部署到我们的测试环境时,我们得到:
XMLHttpRequest cannot load
http://mntest.ktws.XXX.com/api/Motd/getMotdHtml. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://mntest.XXX.com' is therefore not
allowed access. The response had HTTP status code 404.
奇怪的是 - 网络服务站点的 URL 存储在该网站的 web.config 中。如果我们在测试环境中手动编辑网站的 web.config,并将其指向 QA 环境中的 webservices 站点,一切正常。
我在 QA 和 TEST 的 Web 服务站点的 web.config 上做了一个差异,除了数据库连接字符串中的不同服务器名称外,它们是相同的。我不知道为什么这两个网站的行为不同。
我们已经编写了代码,应该可以处理 CORS 调用。在Global.asax.cs中,我们实现了Application_BeginRequest:
protected void Application_BeginRequest(object sender, EventArgs e)
{
var origin = HttpContext.Current.Request.Headers["origin"];
if (origin != null)
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
if (HttpContext.Current.Request.HttpMethod == HttpMethod.Options.Method)
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "DELETE,GET,HEAD,POST,PUT,TRACE");
// Accept whatever headers they've asked to send us
var requestedHeaders = HttpContext.Current.Request.Headers["Access-Control-Request-Headers"];
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", requestedHeaders);
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
// This aborts the response, ending any future processing. Which is always a bad idea, except when it isn't.
// (It seems to be the usual process in dealing with HttpOPTIONS)
HttpContext.Current.Response.End();
}
}
当我们在 QA 中对网络服务进行调用时,我们在请求中看到:
GET http://vm-qaweb2.XXX.net/XXX_webservice/api/Motd/getMotdHtml HTTP/1.1
Host: vm-qaweb2.XXX.net
Connection: keep-alive
Cache-Control: max-age=0
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://mntest.XXX.com
authenticationToken: undefined
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
Referer: http://mntest.XXX.com/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
在回复中是这样的:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://mntest.XXX.com
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 17 Jun 2015 21:26:43 GMT
Content-Length: 1064
[The expected content for the message-of-the-day]
在测试中对网络服务进行调用,我们在请求中看到:
OPTIONS http://mntest.ktws.XXX.com/api/Motd/getMotdHtml HTTP/1.1
Host: mntest.ktws.XXX.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: http://mntest.XXX.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
Access-Control-Request-Headers: accept, authenticationtoken
Accept: */*
Referer: http://mntest.XXX.com/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
我们在响应中看到了这一点:
HTTP/1.1 404 Not Found
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 17 Jun 2015 21:30:58 GMT
Content-Length: 1136
Set-Cookie: NSC_UFTU!L1-WNXFC0-1=ffffffffc3a02c7445525d5f4f58455e445a4a423660;expires=Thu, 18-Jun-2015 05:28:54 GMT;path=/;httponly
[The expected content for the message-of-the-day]
并且在 Chrome 的开发者工具中,我们看到错误:
XMLHttpRequest cannot load
http://mntest.ktws.XXX.com/api/Motd/getMotdHtml. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://mntest.XXX.com' is therefore not
allowed access. The response had HTTP status code 404.
对于它的价值,getMotdHtml() 控制器:
[HttpGet]
[ActionName("getMotdHtml")]
[AllowAnonymous]
public string getMotdHtml()
{
try
{
string html = "";
html = this.motdWrangler.getMotdHtml();
return html;
}
catch (Exception ex)
{
try
{
this.logger.logException(ex, "Exception in getMotdHtml");
}
catch
{
}
return "";
}
}
无论发生什么情况,它都不会返回 404 响应。然而我们得到了一个 404 状态码。尤其令人困惑的是,我们的响应包含预期的 message-of-the-day 文本,只有在执行 getMotdHtml() 操作后才能获得该文本。但如果它有,为什么 404,为什么 Access-Control-Allow-Origin 没有在响应中返回,而 Application_BeginRequest() 必须添加它?
请记住,这不是两个不同的应用程序 - 它是部署到两个不同服务器的相同构建。一方面,它有效,另一方面,它没有,尽管 web.configs 中没有相关差异。
帮忙?
看起来问题可能出在其中一台服务器上安装了 WebDAV:
http://brockallen.com/2012/10/18/cors-iis-and-webdav/
我将这些更改添加到 web.config,我们之前看到的错误消失了。 (当然,我们现在看到了不同的问题,与此无关,但是,这就是编程;)
我们有一个系统,由一个用 ASP.NET/MVC 编写的网站和一个用 ASP.NET/WEBAPI 编写的网络服务站点组成。用户从网站加载页面,使用 JQuery.
调用 Web 服务站点 AJAX我们正在使用 VS2013 构建它,并使用 MS 的 Web 部署对其进行部署,运行 来自 Jenkins 中配置的作业,因此在 fumble-finger 期间,人们没有太多机会进行某些操作安装。
我们的问题 - 当我们将这两个站点部署到我们的 QA 环境时,一切正常。我们可以访问 Web 服务并加载页面,他们对 Web 服务进行 AJAX 调用,Bob 是你的叔叔。
但是当我们将这两个站点部署到我们的测试环境时,我们得到:
XMLHttpRequest cannot load http://mntest.ktws.XXX.com/api/Motd/getMotdHtml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mntest.XXX.com' is therefore not allowed access. The response had HTTP status code 404.
奇怪的是 - 网络服务站点的 URL 存储在该网站的 web.config 中。如果我们在测试环境中手动编辑网站的 web.config,并将其指向 QA 环境中的 webservices 站点,一切正常。
我在 QA 和 TEST 的 Web 服务站点的 web.config 上做了一个差异,除了数据库连接字符串中的不同服务器名称外,它们是相同的。我不知道为什么这两个网站的行为不同。
我们已经编写了代码,应该可以处理 CORS 调用。在Global.asax.cs中,我们实现了Application_BeginRequest:
protected void Application_BeginRequest(object sender, EventArgs e)
{
var origin = HttpContext.Current.Request.Headers["origin"];
if (origin != null)
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
if (HttpContext.Current.Request.HttpMethod == HttpMethod.Options.Method)
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "DELETE,GET,HEAD,POST,PUT,TRACE");
// Accept whatever headers they've asked to send us
var requestedHeaders = HttpContext.Current.Request.Headers["Access-Control-Request-Headers"];
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", requestedHeaders);
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
// This aborts the response, ending any future processing. Which is always a bad idea, except when it isn't.
// (It seems to be the usual process in dealing with HttpOPTIONS)
HttpContext.Current.Response.End();
}
}
当我们在 QA 中对网络服务进行调用时,我们在请求中看到:
GET http://vm-qaweb2.XXX.net/XXX_webservice/api/Motd/getMotdHtml HTTP/1.1
Host: vm-qaweb2.XXX.net
Connection: keep-alive
Cache-Control: max-age=0
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://mntest.XXX.com
authenticationToken: undefined
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
Referer: http://mntest.XXX.com/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
在回复中是这样的:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://mntest.XXX.com
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 17 Jun 2015 21:26:43 GMT
Content-Length: 1064
[The expected content for the message-of-the-day]
在测试中对网络服务进行调用,我们在请求中看到:
OPTIONS http://mntest.ktws.XXX.com/api/Motd/getMotdHtml HTTP/1.1
Host: mntest.ktws.XXX.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: http://mntest.XXX.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
Access-Control-Request-Headers: accept, authenticationtoken
Accept: */*
Referer: http://mntest.XXX.com/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
我们在响应中看到了这一点:
HTTP/1.1 404 Not Found
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 17 Jun 2015 21:30:58 GMT
Content-Length: 1136
Set-Cookie: NSC_UFTU!L1-WNXFC0-1=ffffffffc3a02c7445525d5f4f58455e445a4a423660;expires=Thu, 18-Jun-2015 05:28:54 GMT;path=/;httponly
[The expected content for the message-of-the-day]
并且在 Chrome 的开发者工具中,我们看到错误:
XMLHttpRequest cannot load http://mntest.ktws.XXX.com/api/Motd/getMotdHtml. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mntest.XXX.com' is therefore not allowed access. The response had HTTP status code 404.
对于它的价值,getMotdHtml() 控制器:
[HttpGet]
[ActionName("getMotdHtml")]
[AllowAnonymous]
public string getMotdHtml()
{
try
{
string html = "";
html = this.motdWrangler.getMotdHtml();
return html;
}
catch (Exception ex)
{
try
{
this.logger.logException(ex, "Exception in getMotdHtml");
}
catch
{
}
return "";
}
}
无论发生什么情况,它都不会返回 404 响应。然而我们得到了一个 404 状态码。尤其令人困惑的是,我们的响应包含预期的 message-of-the-day 文本,只有在执行 getMotdHtml() 操作后才能获得该文本。但如果它有,为什么 404,为什么 Access-Control-Allow-Origin 没有在响应中返回,而 Application_BeginRequest() 必须添加它?
请记住,这不是两个不同的应用程序 - 它是部署到两个不同服务器的相同构建。一方面,它有效,另一方面,它没有,尽管 web.configs 中没有相关差异。
帮忙?
看起来问题可能出在其中一台服务器上安装了 WebDAV:
http://brockallen.com/2012/10/18/cors-iis-and-webdav/
我将这些更改添加到 web.config,我们之前看到的错误消失了。 (当然,我们现在看到了不同的问题,与此无关,但是,这就是编程;)