Cache Storage API, can't get header back - javascript

I would like to a check for max-age so I remove items from cache when they get old, but I can't get my own header back for some reason.
export function cacheResponse(url, response) {
caches.open('my-cache').then(function(cache) {
cache.put(url, new Response(JSON.stringify(response), {
headers: {
'Cache-Control': 'max-age=1',
'Content-Type': 'application/json;charset=UTF-8'
}
}));
});
}
cacheResponse('/hello', {hello: "world"})
I can see this working in the Application tab in chrome and I can see those 2 headers in the preview, but when I pull the item back out the headers object is null.
cache.match(url).then(async function(object) {
console.log(object.headers) // null
var body = await object.clone().json(); // {hello: "world"}
})
The object looks like this
object: Response
body: ReadableStream
bodyUsed: false
headers: Headers
__proto__: Headers
ok: true
redirected: false
status: 200
statusText: ""
type: "default"
url: ""
Seems like I should be able to lookup the headers from calling match() no?

That should work; you should be able to call response.headers.get('cache-control') to retrieve the value (assuming this is a same-origin response).
Here's a snippet of code that I just tested which worked when run in the JS console:
async function test() {
const constructedResponse = new Response('test', {
headers: {'cache-control': 'max-age=1'}
});
const cache = await caches.open('test');
cache.put('/test', constructedResponse);
const matchedResponse = await cache.match('/test');
console.log(`cache-control: ${matchedResponse.headers.get('cache-control')}`);
}

Related

Getting variable from array then pass to url on nodejs request module

I have this array and need to pass all the variables inside the request url.
I've tried as result.variable1, result['variable1'], result[0], but nothing works.
How can access each variable inside the array and pass to url?
result.push({variable1: string1, variable2: string2});
request.post({
url: "mydomain.com/text="Hi"+result[variable1]+"\\n"+result[variable2]+"Hello!",
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
},
rejectUnauthorized: false,//add when working with https sites
requestCert: false,//add when working with https sites
agent: false,//add when working with https sites
form: {
myfield: "myfieldvalue"
}
}, function (response, err, body){
console.log('Body:',JSON.parse(body));
}.bind(this));
result.push({variable1: string1, variable2: string2});
This will result in the array becoming as
result = [{variable1: string1, variable2: string2}].
So if you want 'variable1', you need to access it as result[0].variable1.

Extracting data from a fetch() in Javascript

I have a simple fetch request like this:
fetch('/data', {method: 'POST', credentials: 'same-origin', body: {'name': 'alice'}}).then(function(response){
console.log('reply:');
console.log(response);
});
Basically it should send a POST request to the local address /data with some parameters in it (same thing as an HTML form does) and then return the reply it gets (the /data page simply prints out "this is a test response")
But when I look at the console.log(response); it looks like this:
Response { type: "basic", url: ".../data", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers, bodyUsed: false }
The actual string returned by the page /data ("this is a test response") is nowhere to be found.
So how can I retrieve the actual returned string then?
To read the body of the response, you need to actually do that. See the details on MDN (here, here, and here), but in brief, if you want the body as text, then:
fetch(/*...*/)
.then(function(response) {
return response.text();
})
.then(function(responseText) {
// ...
});

Express.js http call inside route doesn't update variable

I'm building a REST api on top of express.js. I am having trouble updating variables inside my routes.
Example:
I'm calling app.get("/wp/page/create/:id", function(req, res)
Inside this route I start by calling a http request using request-promise library. The response of this call I use in a nested http call.
I use a global variable for the headers for the nested call, and it's to the header a i need to make changes by using the etag variable.
Code:
global.postHeaders = headers;
postHeaders['X-HTTP-Method'] = "MERGE";
postHeaders['Content-Type'] = 'application/json;odata=verbose';
postHeaders['X-RequestDigest'] = spContext;
request.get({
url: "xxx",
headers: headers,
json: true
}).then(function(response) {
var etag = response.d.__metadata.etag
postHeaders['If-Match'] = etag;
request.post({
url: "xxx",
type: "POST",
body: data,
headers: postHeaders,
json: true
}).then(function(data) {
res.send(data).end()
console.log("All done!");
})
})
When i start the server up and enter the route everything works fine. When i when try to hit it again the etag variables is still the same, even though it should be updated.
If I restart the server it works the again on the first attempt but fails on the second/third.
Any idea what I am doing wrong?
I have resolved the issues. The simple solution was to clear the headers containing the variable.
global.postHeaders = headers;
postHeaders['X-HTTP-Method'] = "MERGE";
postHeaders['Content-Type'] = 'application/json;odata=verbose';
postHeaders['X-RequestDigest'] = spContext;
request.get({
url: "xxx",
headers: headers,
json: true
}).then(function(response) {
var etag = response.d.__metadata.etag
postHeaders['If-Match'] = etag;
request.post({
url: "xxx",
type: "POST",
body: data,
headers: postHeaders,
json: true
}).then(function(data) {
postHeaders['If-Match'] = "";
res.send(data).end()
console.log("All done!");
})
})
postHeaders is a global variable. is headers in global.postHeaders = headers; also a global varaible ? Whatever you are trying to do here is grossly wrong. postHeaders variable will be shared across multiple request. so you will hit a scenario where postHeaders['If-Match'] value might be empty string or the etag .
Try this instead of the first line
var postHeaders = Object.assign({}, headers);
Not sure what you are trying, but at-least this statement will subside the huge error in the code. This will create a new header object for each request.

How to add data to request body while proxying it

I have a call made from my client that passes in some post data like this:
function doSomethingApi(email) {
return axios({
method: 'post',
url: `/api`,
data: {
scan_refference: 'ref',
user_email: email
}
})
}
On the server side this gets proxied to apply certain secrets:
app.post('/api', (req, res) => {
const url = 'https://my.api.com';
req.pipe(request({
url,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
},
auth: {
user: secrets.USERNAME,
pass: secrets.PASSWORD
},
body: {
value1: `${secrets.VALUE1}`,
value2: `${secrets.VALUE2}`
}
})).pipe(res);
});
request and axios are just 2 different http libraries I use, one is preferred for client other for server, thats all. Issue now is that I am overwriting body in my proxy, where as I want to simply add value1 and value2 to existing body passed from client.
First get the body from the initial call as a JSON object. This depends on what you use, but e.g. in Express you could:
app.use(express.bodyParser());
Then
var previousBody = req.body
Finally merge the initial JSON with whatever you want (NOTE: this means your client will definitely not be able to use the "value1" and "value2" properties, because they will be overwritten)
body: Object.assign(previousBody, {
value1: `${secrets.VALUE1}`,
value2: `${secrets.VALUE2}`
})

HTTPS request not posting body of REST request

I'm trying to POST to an API endpoint on my server. I know my endpoint works because if I use Advanced REST Client, I can hit it and get a JSON response as expected. The problem seems to be that no data is being sent in the body of my request despite calling request.write(postData) which contains a key, value pair. Without this data being sent in the body, my server returns a 401 error as expected without this information. Printing out the content of the POST server-side is empty but I'm clueless as to why it's empty.
var postData = querystring.stringify({
"access_token" : accessToken,
"id": applianceId
});
var serverError = function (e) {
log("Error", e.message);
context.fail(generateControlError(requestName, "DEPENDENT_SERVICE_UNAVAILABLE", "Unable to connect to server"));
};
var callback = function(response) {
var str = "";
response.on("data", function(chunk) {
str += chunk.toString("utf-8");
});
response.on("end", function() {
result = generateResult(CONTROL, requestName.replace("Request", "Confirmation"), messageId);
context.succeed(result);
});
response.on("error", serverError);
};
var options = {
hostname: REMOTE_CLOUD_HOSTNAME,
port: 443,
path: REMOTE_CLOUD_BASE_PATH + "/" + endpoint,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
};
var request = https.request(options, callback);
request.on("error", serverError);
//This doesn't seem to write anything since if I print out the POST
//data server-side it's empty; however, if I print out the value of
//postData here, it looks as expected: 'access_token=xxxxx'
request.write(postData);
request.end();
I have testing you code again httpbin.org/post and it seems that it is working.
I believe that the issue related to, that your should POST application/json and not "application/x-www-form-urlencoded
Please try to change the header
headers: {
"Content-Type": "application/json"
}
Then, try to change the postData to JSON string:
var postData=JSON.stringify({access_token:"xxxxx"})
To be sure that problem you success to send and the problem is not local (maybe there is an issue in your server), change the target to mirror URL:
var options = {
hostname: "httpbin.org",
path:'/post',
port: 443,
method: "POST",
headers: {
"Content-Type": "application/json"
}
};
If there is no problem in your NodeJS version, the is the response you should get: (It is mean that the server got the posted data)
{
"args": {},
"data": "{\"access_token\":\"xxxxx\"}",
"files": {},
"form": {},
"headers": {
"Content-Length": "24",
"Content-Type": "application/json",
"Host": "httpbin.org"
},
"json": {
"access_token": "xxxxx"
},
"origin": "5.29.63.30",
"url": "https://httpbin.org/post"
}
BTW: I really recommend you to move to a library to manage the request for you:
https://github.com/request/request - Very popular
https://github.com/request/request-promise - For popular who like to use the Promise syntax (The next thing in JavaScript)
https://github.com/visionmedia/superagent - For people who like to write same code in Browser & Server

Categories