我有一个ASP.NET Web API 2服务。多个客户端(角度)应用程序与该服务进行通信。应用程序和服务发布在不同的子域上,如下所示:
service.mydomain.com
app1.mydomain.com
app2.mydomain.com
我使用了Microsoft.AspNet.WebApi.Cors - NuGet包来启用CORS,它运行正常,除了一个场景: 当用户打开一个应用程序(app1.mydomain.com)时。 然后导航到另一个(app2.mydomain.com)。然后按下浏览器后退按钮。下面的CORS错误:
The 'Access-Control-Allow-Origin' header has a value 'http://app2.mydomain.com' that is not equal to the supplied origin.
Origin 'http://app1.mydomain.com' is therefore not allowed access
我配置了Microsoft.AspNet.WebApi.Cors - NuGet包,如下所示:
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute(
//to-do allow cross domains for all maarif.com sites
origins: "*", //and also tried "http://app1.mydomain.com, http://app2.mydomain.com" gives same result
headers: "*",
methods: "*") {SupportsCredentials = true};
config.EnableCors(cors);
}
我在服务器上跟踪了Origin标头值。 我将以下代码放入服务' global.asax' :
protected void Application_BeginRequest()
{
var origin = HttpContext.Current.Request.Headers["Origin"];
if (origin != null )
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
}
}
当用户点击后退按钮形式' app2.mydomain.com'对于app1.mydomain.com',随请求发送的来源是' app2.mydomain.com',这就是服务允许访问的内容:HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", 'app2.mydomain.com');
有什么方法吗?
请注意,我无法提供' *'因为请求已经过身份验证。
答案 0 :(得分:3)
问题是由于浏览器的缓存机制所致。因为当您单击“后退”按钮时,浏览器将使用缓存中的数据,甚至用于AJAX请求。
为此,浏览器不会重新发送CORS预检信息来检查Access-Control-Allow-Origin
中上一页的来源。然后它将使用最新的Access-Control-Allow-Origin
,即app2.mydomain.com
,这样app1.mydomain.com
应该会失败。
一个简单的解决方案是在api查询字符串的末尾添加时间戳或随机字符串,例如:
let url = 'https://service.mydomain.com/xxxxx?v=' + Date.now();
但是它将忽略Access-Control-Max-Age
,这会使CORS预先处理对service.mydomain.com
的每个请求。
或者您可以在新窗口中强制打开到其他原点的所有链接,这样就无法执行BACK操作。
除了这些,我找不到其他解决方案。
已更新:
在此答案之后,我进行了测试,然后找到了最终解决方案:
在service.mydomain.com
中添加以下HTTP响应标头,然后一切正常。
Cache-Control: no-store,no-cache,must-revalidate
Pragma: no-cache
仅禁用AJAX请求的所有缓存。而且CORS Max-age也可以使用。
现在,它可以在Chrome和Firefox中使用。我没有尝试其他浏览器,但我认为应该没什么不同。
答案 1 :(得分:0)
您是否尝试过将StratUp.cs文件放入:
var corsPolicy = new CorsPolicy
{
AllowAnyMethod = true,
AllowAnyHeader = true,
SupportsCredentials = true,
Origins = { "http://site1.example.com", "http://site2.emaple.com.:38091", "http://localhost:39372" }
};
app.UseCors(new CorsOptions
{
PolicyProvider = new CorsPolicyProvider
{
PolicyResolver = context => Task.FromResult(corsPolicy)
}
});
在您的网络服务器部分的web.config中可能是这样的:
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>