Web API CORS请求和浏览器缓存

时间:2014-06-09 11:38:44

标签: asp.net-web-api cors asp.net-web-api2

我们在我们的应用程序中使用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, 最大

0 个答案:

没有答案