我正在为一个移动应用程序创建一个Node.js / Express后端,该应用程序使用RESTful方法向API发出请求,我可以使用此API返回的JSON数据供用户在我的移动应用程序中使用。
我的困惑在于“ under the hood ”之间存在的差异,以及在使用适用于浏览器和服务器的特定标头时自动处理的问题 VS 在通过终端进行卷曲请求时,您将运行多次,使用不同的标头发送和响应
我必须使用条件GETs约定,其中:
1)所有响应都返回HTTP Cache-Control标头。它的内容表示可以使用缓存响应多长时间来减少不必要的API请求。
2)除此之外,每个响应都会返回HTTP ETag标头。它的内容将用于HTTP If-None-Match 标头中对同一资源的后续请求。如果缓存的信息仍然有效,则API将返回状态代码304 Not Modified。
访问此API的客户端必须使用这种技术,也称为条件GET。
A)返回我请求的数据。
B)返回 Etag 以用于将来的请求
)C)返回 Cache-Control 标头以了解数据可缓存多长时间,像这样:
第一次请求:
$ curl -v "https://api.example.com/data/3" -X GET \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-u token:secret
性反应:
< HTTP/1.1 200 OK
< Date: Wed, 01 Sep 2017 22:22:22 GMT
< ETag: "xxxxxxxxxxxxxxxxxxxxxxx" <-----Got Etag
< Last-Modified: Wed, 09 Sep 2015 11:11:11 GMT
< Content-Type: application/json; charset=utf-8
< Cache-Control: max-age=3600, private <-----and Cache-Control is set
{"data":{"id":1, "...": "..."}} to 3600 seconds (1 hour).
在这里,我理解Cache-Control
标题指定我刚获得的数据有效期为3,600秒,即1小时。因此,我可以在下一个小时内使用返回的数据信息,而无需再次从API请求数据。在该时间段之后,可以对API进行另一个请求。这次我包括我在一小时前收到的返回xxx.....
ETag
值(因为Cache-Control
设置的时间长度),并在If-None-Match
标题中使用它我提出了另一个请求:
未来要求:
$ curl -v "https://api.example.com/data/3" -X GET \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "If-None-Match: xxxxxxxxxxxxxxxxxxxxxxx" <--Added here
-u token:secret
未来回应:
< HTTP/1.1 304 Not Modified <--Got 304 because the
< Date: Wed, 23 Sep 2015 20:24:20 GMT
< ETag: "xxxxxxxxxxxxxxxxxxxxxxx" <-- `Etag` returned is the same
< Last-Modified: Wed, 09 Sep 2015 11:45:39 GMT (so I know it hasn't changed)
< Cache-Control: max-age=3600, private
< Connection: close
所以这导致我有几个问题:
我正在使用相当直接的Node.js request模块来提出我的请求:
var request = require('request');
var options = {
url: 'https://api.example.com/data/3',
headers: { <------ Setting up Headers
'Content-Type': 'application/json', Note: no "If-None-Match"
'Accept': 'application/json'
'Authorization: Basic QQWERQWERWQER='
}
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
var data = body <------ Got 200 response and loaded
} return data into data varible
}
request(options, callback);
因此,在我的Express服务器上发出第一个请求后,它(我的服务器)可以确定是否需要根据Cache-Control
标头和{{1}从网络或缓存中获取该内容}。那怎么办呢?
我是否需要以编程方式/编写代码来每小时执行此操作?因此,我必须编写代码来抓取ETag
这样的
etag
并创建第二组标题
if (!error && response.statusCode == 200) {
var data = body;
var etag = response.headers.etag <------ Grab this
}
像我做第二次卷曲的时候一样吗? (我这样做了,它会阻止每个请求都没有返回任何状态代码,如果这是它的完成方式,那就是我做错了什么?)
或将 headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
'Authorization: Basic QQWERQWERWQER='
'if-none-match': etag <------ Adding it here
}
标头设置为Cache-Control
和max-age=3600, private
(在我的示例中设置为Etag
)的初始响应是否自动在我的Express服务器上设置缓存告诉它采取相应行动,它想要这个资源,它在一小时内再次检查它,而不必做任何事情告诉它?
现在每当我在移动应用中请求一个需要某个资源的资源(比如我的示例https://api.example.com/data/3中的资源)时,它会触发我的Express服务器代表移动应用用户获取它把它返还。但是,当我多次请求相同的资源时,API每次都会返回200响应。在第一个请求之后,每个请求应该以304响应。那么这里发生了什么/我在做什么/理解错误?为什么我不会得到304响应?