我们在我们的应用程序中使用web api cors请求,并且许多api调用可由客户端(即浏览器)缓存。
Chrome和Firefox尊重缓存控制标头并按预期缓存响应,但Internet Explorer和Safari始终执行新请求。
控制器:
[EnableCors("*", "*", "*")]
public HttpResponseMessage Get()
{
var response = Request.CreateResponse(HttpStatusCode.OK, "test");
response.Headers.CacheControl = new CacheControlHeaderValue
{
Public = true,
MaxAge = DateTime.UtcNow.AddDays(7) - DateTime.UtcNow
};
response.Headers.ETag = new EntityTagHeaderValue("\"" + Guid.NewGuid().ToString() + "\"");
return response;
}
JQuery ajax请求(从其他域发出):
$.ajax({
type: 'GET',
url: 'http://next.b.se/api/tests'
}).done(function (data) {
$("#v").text("Done!");
}).error(function (jqXHR, textStatus, errorThrown) {
$("#v").text("Error");
});
请求(来自提琴手):
GET http://next.b.se/api/tests HTTP/1.1
Referer: http://hitta.a.se/local.html
Accept: */*
Accept-Language: en,sv-SE;q=0.5
Origin: http://hitta.a.se
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: next.b.se
DNT: 1
Connection: Keep-Alive
回应(来自提琴手):
HTTP/1.1 200 OK
Cache-Control: public, max-age=604800
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
ETag: "4bfa551b-61db-42cb-8877-25f20a0ec94d"
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: *
Date: Mon, 09 Jun 2014 10:58:12 GMT
Content-Length: 192
当加载页面hitta.a.se/local.html,从中完成跨域请求时,第一次清理浏览器缓存后,所有浏览器(IE,CHrome,FF和Safari)都向api端点如预期的那样。
第二次在新标签页中加载页面hitta.a.se/local.html并点击返回Chrome和FF获取缓存版本,即没有向api发出请求(正如预期的那样由于缓存 - 根据Fiddler和开发工具,控制头。问题是IE发出新请求,它不使用缓存版本,并且它不使用etag和if-none-match标头发出条件get。我知道api不处理if-none-match请求,但问题是浏览器根本不执行条件请求。
如果我们希望IE和Safari使用缓存的响应,这是合适的方法吗?
注意!此问题也发布在codeplex https://aspnetwebstack.codeplex.com/discussions/548035上。我不知道web api guru最活跃的地方!
更新2014-06-10
如果我们更改api调用以使用JSONP而不是Ajax Internet Explorer根据缓存头缓存响应。
JQuery JSONP请求:
$.ajax({
type: 'GET',
url: 'http://next.b.se/api/tests',
dataType: 'jsonp',
contentType: 'text/javascript',
jsonpCallback: 'p',
cache: true
}).done(function (data) {
$("#v").text(data.v);
}).error(function (jqXHR, textStatus, errorThrown) {
$("#v").text("Error");
});
Safari仍会执行新请求。 Safari的任何已知解决方法?即强制Safari在跨域XHR请求或JSONP请求中尊重缓存头?
BR, 最大