在 AppDelegate.m 中,我配置了:
NSURLCache *sharedURLCache = [[NSURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024 diskCapacity:100 * 1024 * 1024 diskPath:@"FhtHttpCacheDir"];
Run Code Online (Sandbox Code Playgroud)
然后是http请求:
- (void) testRestfulAPI{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://192.168.0.223:8000/v1/topictypes"]];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
NSError *error = nil;
if (!error) {
NSURLSessionDataTask *downloadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
if (httpResp.statusCode == 200) {
NSDictionary* json = …Run Code Online (Sandbox Code Playgroud) 目前 React Native 在fetch调用中缓存的默认行为是什么?官方 FB 指南只是说“看看 Mozilla!” 但我们不是在网络浏览器上。由于中间件,我认为缓存行为在这里是自定义的。
假设我这样做: fetch("https://exampleserver.com/myfile.json")
请求是否在调用后自动缓存?
是否myfile.json缓存了整个“会话”的请求内容(即:App 正在运行 active/bg,但未被用户强制关闭)。
AsyncStoragefetch网址再次导致应用程序读取高速缓存。myfile.json多次请求,它是否会在那时基本上忽略缓存并进行所有这些单独的调用?(我在调试器中看到这种行为)当我强制关闭应用程序并重新打开时,此缓存是否仍然存在?
iOS 和 Android 中的这种行为有什么不同吗?
世博会对此有影响吗?
至少知道其中的一些将有助于决定我是否需要像这样使用 AsyncStorage 编写自定义缓存情况 https://gist.github.com/dslounge/18e555250a8df1f8218d702b21910eeb
创建使用 POST/PUT 的 REST API 很简单。它们是非幂等的,因此默认情况下不会被浏览器缓存。
但是,在创建 GET 端点时,事情变得更棘手了。我担心浏览器(或特定浏览器)在默认情况下会尝试缓存 GET 请求,而我最终会得到陈旧的数据。
让我们以端点为例GET /articles/123/comments。
尽管这个端点是一个 GET 端点,但每个请求都可以返回不同的内容,因为文章的评论被提交。
假设没有与响应提供的缓存相关的标头。
content-length: 2518
content-type: application/json
date: Thu, 17 Oct 2019 07:51:59 GMT
status: 200
Run Code Online (Sandbox Code Playgroud)
似乎有不同的策略来解决这个问题,但最好的方法是什么?
通过唯一的查询字符串缓存破坏我的 GET 调用?
例如。 GET /articles/123/comments?nonce=12312310980923409
添加Cache-Control: no-cache(这会一直受到尊重吗?)
添加ETag: xyz_HASH_OF_MY_LIST_OF_COMMENTS?
添加Cache-Control: max-age=0(禁用缓存)
添加Cache-Control: max-age=60(以减少缓存的最大持续时间)
只是不要担心并假设没有像ETag, Last-ModifiedGET 请求这样的标头不会被任何浏览器缓存?
我正在运行启用了缓存插件的 WP 网站。该站点运行缓慢,因此我决定检查哪个元素加载时间更长。直接到 F12(chrome 网络工具),然后从那里选择网络标签。我看到但我不明白的是为什么有些文件是从磁盘缓存加载的,而其他文件则不是。请参阅附图(“尺寸”栏)
所以,如果你知道答案,请分享。
谢谢!
我试图使用 HTTP 缓存来做一些简单的事情,但我无法让它工作。
我正在使用以下选项fetch()。
fetch('test', {
cache: 'force-cache',
headers: {
'Cache-Control': 'max-age=3600',
'Pragma': 'max-age=3600', // added for redundancy
}
})
.then( response => response.json() )
.then( data => console.log(data) )
.catch( error => console.error(error) )
.finally( () => console.log('Done') );
Run Code Online (Sandbox Code Playgroud)
端点test只是返回一个具有以下格式的json
{
"date": "...", /* date in 'Y-m-d H:i:s' format */
}
Run Code Online (Sandbox Code Playgroud)
我已确保响应也具有 Cache-Control 标头。当我检查响应标头时我可以看到它。
HTTP/1.1 200 好 服务器:阿帕奇 缓存控制:公共,最大年龄=3600 内容长度:30 保持活动:超时=5,最大值=94 连接:保持活动状态 内容类型:application/json;字符集=UTF-8
请求标头似乎也是正确的。
连接:保持活动状态 编译指示:最大年龄=3600 缓存控制:max-age=3600 接受: */* Sec-Fetch-Site:同源 Sec-Fetch-Mode:cors Sec-Fetch-Dest:空
我尝试在一分钟内一遍又一遍地运行相同的获取,期望获得相同的日期,不变,但结果总是“新的”,可以这么说。
我对 HTTP …
我正在开发一个新的REST-ful API,该API的主要/唯一使用者是智能/非Web浏览器客户端。我有一个由后台进程(而不是由客户端本身)维护/更新的集合资源。第一次迭代所需的唯一内容类型是JSON。URI类似于:
/items/ -代表项目集合的资源。/items/123-代表ID为的单个项目的资源123。虽然客户端将不会创建新项目,也不会更新集合以添加/删除项目,但它将更新单个项目中的某些值。我的计划是使用我自己的JSON补丁格式,使用HTTP PATCH更新项目资源。
将有许多并发客户端读取项目,并同时更新不同的项目,并偶尔对同一项目进行并发更新,尽管允许一定程度的“最终一致性”,但我想将其设计为“缓存友好” “一种可能的方式。阅读RFC的PATCH,我发现对PATCH的成功响应后,如果有响应,则应使用响应更新Request-URI的缓存。问题归结为:
我要:
A)在/items/集合资源JSON 表示中包含各个项目的完整表示,然后将PATCH发送到/items/URI,并以补丁格式包括要更新的项目?
优点:
N为了显示资源列表而执行请求数items客户端更新项目时使的所有缓存无效。缺点:
要么
B)在资源集合的JSON表示中,仅包括指向所包含项目的链接,并让客户端在发现集合中的哪些项目后请求各个项目。HTTP PATCH将发送到单个项目URI(例如/items/123)
优点:
缺点:
N+1请求以显示项目的完整列表。我应该在哪里存储给定资源的ETag?
获取资源并在每次请求时动态计算ETag:
$resource = $repository->findByPK($id); // query
// Compute ETag
$etag = md5($resource->getUpdatedAt());
$response = new Response();
$response->setETag($etag);
$response->setLastModified($resource->getUpdatedAt());
if($response->isNotModified($this->getRequest())) {
return $response; // 304
}
Run Code Online (Sandbox Code Playgroud)
在制作INSERT和UPDATE语句有点慢时节省一点CPU时间(我们使用触发器来更新ETag):
$resource = $repository->findByPK($id); // query
$response = new Response();
$response->setETag($resource->getETag());
$response->setLastModified($resource->getUpdatedAt());
if ($response->isNotModified($this->getRequest())) {
return $response;
}
Run Code Online (Sandbox Code Playgroud)
这就像方法B,但ETag存储在一些缓存中间件中.
我的laravel4应用程序中有一个小型图像生成器。生成图像大约需要700毫秒,因此我开始在服务器上缓存生成的结果,并将其返回给浏览器,这样可以节省一些时间。
由于图像一旦生成就永远不会改变,所以我想告诉浏览器在本地缓存图像,并使用以下代码完成了此操作:
$path = $cacheFolderPath . $cacheFileName;
if (File::exists( $path )){
$response = Response::make(File::get($path));
$response->header('Content-Type', 'image/png');
$response->header('Content-Disposition', 'inline; filename="'.$cacheFileName.'"');
$response->header('Content-Transfer-Encoding', 'binary');
$response->header('Cache-Control', 'public, max-age=10800, pre-check=10800');
$response->header('Pragma', 'public');
$response->header('Expires', date(DATE_RFC822,strtotime(" 2 day")) );
$response->header('Last-Modified', date(DATE_RFC822, File::lastModified($path)) );
$response->header('Content-Length', filesize($path));
return $response;
}
Run Code Online (Sandbox Code Playgroud)
这会将带有状态代码的图像发送200 OK到带有以下标头的浏览器:
Cache-Control:max-age=10800, pre-check=10800, public
Connection:Keep-Alive
Content-Disposition:inline; filename="pie_0_normal.png"
Content-Length:2129
Content-Transfer-Encoding:binary
Content-Type:image/png
Date:Wed, 07 Aug 2013 10:29:20 GMT
Expires:Fri, 09 Aug 13 10:29:20 +0000
Keep-Alive:timeout=5, max=93
Last-Modified:Wed, 07 Aug 13 10:14:42 +0000
Pragma:public
Server:Apache/2.4.3 (Win32) OpenSSL/1.0.1c PHP/5.4.7
Set-Cookie:laravel_session=767487mhf6j2btv3k01vu56174; …Run Code Online (Sandbox Code Playgroud) 我想使用HTTP代理(例如nginx)来缓存大量/昂贵的请求.这些资源对于任何授权用户都是相同的,但是每个请求的后端都需要检查其身份验证/授权.
这听起来像是Cache-Control: public, max-age=0与nginx指令proxy_cache_revalidate on;一起执行此操作的方式.代理可以缓存请求,但是每个后续请求都需要对后端执行条件GET,以确保在返回缓存资源之前对其进行授权.如果用户未经授权,则后端发送403,如果用户被授权则发送304,并且缓存的资源不是陈旧的,或者如果新资源已过期,则发送200.
在nginx max-age=0中设置了if ,根本不缓存请求.如果max-age=1设置,那么如果我在初始请求之后等待1秒,那么nginx会执行条件GET请求,但是在1秒之前它直接从缓存服务它,这对于需要进行身份验证的资源来说显然非常糟糕.
有没有办法让nginx缓存请求但是立即需要重新验证?
请注意,这在Apache 中可以正常工作.以下是nginx和Apache的示例,前两个有max-age = 5,最后两个有max-age = 0:
# Apache with `Cache-Control: public, max-age=5`
$ while true; do curl -v http://localhost:4001/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cache: MISS from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: HIT from …Run Code Online (Sandbox Code Playgroud) 我在我的Symfony 3应用程序中启用了ESI,我将其用于app_dev.php:
$kernel = new AppKernel('dev', true);
$kernel = new AppCache($kernel);
Run Code Online (Sandbox Code Playgroud)
现在我有config.yml:
framework:
esi: { enabled: true }
fragments: { path: /_fragment }
Run Code Online (Sandbox Code Playgroud)
在我的控制器中:
/**
* @Route("/foo/bar/{fooId}", name="AppBundle_Foo_bar")
*/
public function barAction(int $fooId, Request $request)
{
//some database querying from repositroy
$response = $this->render('AppBundle:Foo:bar.html.twig',['foo' => $foo]);
$response->setETag(md5($response->getContent()));
$response->setPublic();
$response->isNotModified($request);
return $response;
}
Run Code Online (Sandbox Code Playgroud)
这是bar.html.twig我要缓存的view(),如下所示:
{{foo}}
Run Code Online (Sandbox Code Playgroud)
现在,我有另一种渲染主视图的方法.
/**
* @Route("/baz/{fooId}", name="AppBundle_Foo_baz")
* @Template
*/
public function bazAction(int $fooId)
{
return [
'fooId' => $fooId
];
} …Run Code Online (Sandbox Code Playgroud) http-caching ×10
caching ×4
http ×3
fetch ×2
http-headers ×2
php ×2
esi ×1
etag ×1
expo ×1
httpresponse ×1
ios ×1
javascript ×1
laravel ×1
laravel-4 ×1
nginx ×1
nsurlcache ×1
nsurlsession ×1
react-native ×1
rest ×1
symfony ×1