Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取角度js的ETag-我需要在服务器端检查吗_C#_Angularjs_Restangular_Etag - Fatal编程技术网

C# 获取角度js的ETag-我需要在服务器端检查吗

C# 获取角度js的ETag-我需要在服务器端检查吗,c#,angularjs,restangular,etag,C#,Angularjs,Restangular,Etag,我正在尝试在angular JS中实现GET请求的etag,到目前为止我已经看到了 而且是三角形的(很复杂但很好)。他们都说它为GET请求提供了内置支持,我想这意味着我不必在服务器端(在c#NET中)编写任何代码 我的假设是对的,还是我必须使用CacheCow或其他东西在报头中查找ETAG并发送304响应 作为背景,我必须使用ETAG而不是缓存(angular),以便从服务器获取最新数据。我是angular http ETAG的作者,因此我只能直接谈论该模块的功能。它装饰Angular的$htt

我正在尝试在angular JS中实现GET请求的etag,到目前为止我已经看到了 而且是三角形的(很复杂但很好)。他们都说它为GET请求提供了内置支持,我想这意味着我不必在服务器端(在c#NET中)编写任何代码

我的假设是对的,还是我必须使用CacheCow或其他东西在报头中查找ETAG并发送304响应


作为背景,我必须使用ETAG而不是缓存(angular),以便从服务器获取最新数据。

我是
angular http ETAG
的作者,因此我只能直接谈论该模块的功能。它装饰Angular的
$http
服务,允许您指定要缓存的请求。下面是我在readme.md中提供的用法示例:

angular
  .module('myApp', [
    'http-etag'
  ])
  .config(function (httpEtagProvider) {
    httpEtagProvider
      .defineCache('persistentCache', {
        cacheService: 'localStorage'
      })
  })

  .controller('MyCtrl', function ($http) {
    var self = this

    $http
      .get('/my_data.json', {
        etagCache: 'persistentCache'
      })
      .success(function (data, status, headers, config, itemCache) {
        // Modify the data from the server
        data._fullName = data.first_name + ' ' + data.last_name
        // Update the cache with the modified data
        itemCache.set(data)
        // Assign to controller property
        self.fullName = data._fullName
      })
      // Synchronous method called if request was previously cached
      .cached(function (data, status, headers, config, itemCache) {
        self.fullName = data._fullName
      })
      .error(function (data, status) {
        // 304: 'Not Modified'--Etag matched, cached data is fresh
        if (status != 304) alert('Request error')
      })
  })

服务器端唯一需要做的就是确保服务器正在发送
ETag
响应头。您可以在这里找到有关如何在Chrome中检查响应头的信息:

嗯,因为某些服务器必须支持发布ETag,而ASP.NET MVC或Web API默认情况下不支持。您必须在服务器上使用某种形式的输出缓存

其中一个项目是Filip Woj的CacheOutput


我想要一个基于$http拦截器的解决方案,因为我需要它与$http的所有用户一起工作,我不能像angular http etag那样只使用$http装饰器,因为angular Translate的$translateProvider.UseStaticFileLoader使用$http,我希望这些调用也被缓存

下面的解决方案是用Typescript编写的,它将从localstorage存储/检索缓存,并且只保留最新的25个缓存项

interface CacheObject {
    data: any;
    etag: string;
    index: number;
}

appModule.config(['$httpProvider', ($httpProvider) => {
    const cacheKey = 'add_your_unique_custom_localstorage_key_here';
    const cacheSize = 25;
    let index = 0;
    let cache: {[key: string]: CacheObject};

    const cacheString = localStorage.getItem(cacheKey);

    if (cacheString == null) {
        cache = Object.create(null);
    } else {
        cache = JSON.parse(cacheString);
        let cacheEntries = Object.entries(cache);

        for (const entry of cacheEntries) {
            // Find largest index
            const entryIndex = entry[1].index;
            if (entryIndex > index) {
                index = entryIndex;
            }
        }
        if (index > Number.MAX_SAFE_INTEGER) {
            // Reset cache if index gets larger than max safe int
            // This is kind of a theoretical problem
            cache = Object.create(null);
            cacheEntries = [];
            index = 0;
        }

        if (cacheEntries.length > cacheSize) {
            // Clean up cache once in a while. Only keep the 25 newest items
            const sortedCacheEntries = cacheEntries.sort((a, b) => {
                return b[1].index - a[1].index;
            });
            sortedCacheEntries.length = cacheSize;
            cache = sortedCacheEntries.reduce(
                (accum, [k, v]) => {
                    accum[k] = v;
                    return accum;
                },
                Object.create(null),
            );
        }
    }

    $httpProvider.interceptors.push(['$q', ($q: ng.IQService) => {
        return {
            response: (response) => {
                const headers = response.headers();
                if (response.status === 200 && headers.etag) {
                    const cacheObject = {
                        data: response.data,
                        etag: headers.etag,
                        index: index++,
                    };
                    cache[response.config.url] = cacheObject;
                    localStorage.setItem(cacheKey, JSON.stringify(cache));
                }
                return response;
            },
            responseError: (response) => {
                if (response.status === 304) {
                    const cacheObject = cache[response.config.url];
                    if (cacheObject != null) {
                        const data = cacheObject.data;
                        const dataString = JSON.stringify(data);
                        const clonedData = JSON.parse(dataString);
                        response.data = clonedData;
                        // Will only recover if we set status to 200
                        response.status = 200;
                        return $q.resolve(response);
                    }
                }
                return $q.reject(response);
            },
            request: (config) => {
                const cacheObject = cache[config.url];
                if (cacheObject != null) {
                    config.headers['If-None-Match'] = cacheObject.etag;
                }
                return config;
            },
        };
    }]);
}]);

如果您发现了您的解决方案,请与我们分享