programing

AngularJS에서 IE 캐시를 방지하는 더 나은 방법?

showcode 2023. 3. 21. 22:41
반응형

AngularJS에서 IE 캐시를 방지하는 더 나은 방법?

현재 서비스/$리소스를 사용하여 Ajax 콜(이 경우 GET)을 발신하고 있으며 IE는 서버에서 새로운 데이터를 가져올 수 없도록 콜을 캐시합니다.IE가 데이터 캐시에 가지 않도록 구글링으로 찾은 기술을 사용하여 난수를 만들어 요청에 추가했습니다.

모든 요청에 cacheKill을 추가하는 것보다 더 나은 방법이 있습니까?

공장 코드

.factory('UserDeviceService', function ($resource) {

        return $resource('/users/:dest', {}, {
            query: {method: 'GET', params: {dest: "getDevicesByUserID"}, isArray: true }
        });

컨트롤러로부터의 콜

$scope.getUserDevices = function () {
        UserDeviceService.query({cacheKill: new Date().getTime()},function (data) {
            //logic
        });
    }

다른 게시물 중 하나에서 설명한 바와 같이 $httpProvider에서 캐시를 글로벌하게 비활성화할 수 있습니다.

myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }    

    // Answer edited to include suggestions from comments
    // because previous version of code introduced browser-related errors

    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
    // extra
    $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
    $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);

바이너리 자이언트가 요청한 대로 답변으로 제 코멘트를 올립니다.서버측 응답에 No-Cache 헤더를 추가하여 이 문제를 해결했습니다.이 작업은 GET 요청에 대해서만 수행해야 합니다.다른 요청은 정상적으로 동작하는 것 같습니다.

binary giant가 노드/모듈에서 이 작업을 수행하는 방법을 게시했습니다.ASP에서 할 수 있습니다.NET MVC는 다음과 같습니다.

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}

ASP 사용하시는 분.NET Web API 2는 다음과 같습니다(Web API는 MVC와 동일한 캐싱 로직을 사용하지 않습니다).

public class NoCacheHeaderFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null) // can be null when exception happens
        {
            actionExecutedContext.Response.Headers.CacheControl =
                new CacheControlHeaderValue { NoCache = true, NoStore = true, MustRevalidate = true };
            actionExecutedContext.Response.Headers.Pragma.Add(new NameValueHeaderValue("no-cache"));

            if (actionExecutedContext.Response.Content != null) // can be null (for example HTTP 400)
            {
                actionExecutedContext.Response.Content.Headers.Expires = DateTimeOffset.UtcNow;
            }
         }
    }
}

WebApiConfig.cs 에 첨부합니다.

public static void Register(HttpConfiguration config)
{
    ....
    config.Filters.Add(new NoCacheHeaderFilter());

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

이를 위해서는 is 인스턴스에서 noCache를 활성화하는 것이 가장 좋은 방법입니다.

노드/표현에서는 IE가 이러한 요구를 캐싱하지 않도록 하기 위해 다음과 같이 동작합니다.

app.use(function noCache(req, res, next) {
    res.header("Cache-Control", "no-cache, no-store, must-revalidate");
    res.header("Pragma", "no-cache");
    res.header("Expires", 0);
    next();
});

대행 수신기를 추가하여 고유한 요청 URL을 생성할 수 있습니다.console.log 콜을 삭제할 수도 있습니다.

myModule.config(['$httpProvider', function($httpProvider) {
 $httpProvider.interceptors.push('noCacheInterceptor');
}]).factory('noCacheInterceptor', function () {
            return {
                request: function (config) {
                    console.log(config.method);
                    console.log(config.url);
                    if(config.method=='GET'){
                        var separator = config.url.indexOf('?') === -1 ? '?' : '&';
                        config.url = config.url+separator+'noCache=' + new Date().getTime();
                    }
                    console.log(config.method);
                    console.log(config.url);
                    return config;
               }
           };
    });

해결 방법:

$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
    console.log('your get response is new!!!');
});

코아즈는 바이너리 거인의 대답과 같다.

app.use(route.get('*', noCache));

function* noCache(path, next){
    this.set('cache-control', 'no-cache, no-store, must-revalidate');
    this.set('pragma',  'no-cache');
    this.set('expires', 0);
    yield next;
}

이 접근방식은 다음과 같습니다.

myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }
    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
}]);

정답입니다. '0'은 If-Modified-Since 헤더의 유효한 값이 아닙니다.유효한 HTTP 날짜여야 합니다.다음은 예를 제시하겠습니다.

If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT

사양에 따라:

수신자는 If-Modified-Since 헤더필드를 무시해야 합니다.
수신된 필드 값이 유효한 HTTP 날짜가 아니거나 요청이 있는 경우
메서드는 GET도 HEAD도 아닙니다.

그러니 후회하기보다는 안전하게 과거의 실제 날짜를 사용하는 것이 좋을 것이다.

서버 출력을 제어할 수 있는 경우 대신 캐싱 헤더를 추가하지 않는 것이 좋습니다.

제 솔루션은Cache-Control: no-cache서버상의 헤더, 추가$templateCache.remove()상태가 바뀌기 전에.angular-ui/router를 사용하고 있습니다.IE11과 엣지 브라우저에 문제가 있었습니다.

$templateCache.remove('/partials/details.html');
$state.go('details');

확실한 해결책은 고유한 URL을 사용하는 것입니다.다만, 초기화 후에 라우터의 URL을 변경하는 방법 브라우저 캐시를 무효로 하는 것은 불가능합니다.통상적인 조작에는 이것이 필요하기 때문입니다.템플릿이 필요 없게 되었을 때 $templateCache에서 템플릿을 삭제할 수 있습니다.( http://docs.angularjs.org/api/ng.$templateCache) )를 참조해 주세요.이러한 새 파일은 다운로드가 완료되는 즉시 캐시에 추가됩니다.

언급URL : https://stackoverflow.com/questions/16971831/better-way-to-prevent-ie-cache-in-angularjs

반응형