Send default POST variable in all Axios requests - javascript

I need to add the default global variable to all my POST requests using Axios.
I'm able to add the parameter using interceptor like:
axios.interceptors.request.use((config) => {
config.params = config.params || {};
config.params['timezone_adjust'] = window.timezone_adjust;
return config;
});
But in this case the url looks like "{url}?timezone_adjust=0
However I want to include the timezone_adjust variable on the request data object instead. Is that possible?

If you want to make a "global" settings to all your POST requests you should prefer using headers instead of body payload
Why? different requests may have different body payload, yet they can share common headers set (it is more common than shared payload)
In that case you can use Global axios defaults
axios.defaults.headers.post['YOUR-COMMON-HEADER'] = 'HEADER-VALUE';
Then you should fetch your headers from request object in your backend

Related

Prevent Axios from sending specific headers

I am working with Vuejs and i have one problem
I want to send custom Headers to my backend API but not to a third Party API.
i have tried to create an axios instance to solve my case to no avail. The Custom Headers are sent to the third Party API which is of course blocked by CORS and thus i dont get the Results i expect. I figure that i did set the custom header globally in the Vue main.js how should i go about exempting the custom headers from being sent to the third party API
The Axios instance created is
var instance = axios.create();
var config = {
method: "get",
url: "//thirdPartyApi",
headers: {
"Content-Type": "application/json",
},
};
const response = instance(config);
and in the main.js file i have
Vue.prototype.$http.defaults.headers.common["customHeader"] = Tokenized;
where Tokenized is my custom Variable
Solution 1 - use different Axios instance for both API's (clean and easy)
Solution 2 - write custom request interceptor and remove the header based on URL of the request...

Can’t access cross-origin response header from frontend JavaScript

I am building a simple web app using ReactJS and create-react-app.
I have a backend API set up on Heroku where I can make POST requests. Everything works fine, except:
When I make a POST request using fetch API, the response is 100% correct but it only gives me 2 standard headers. I want to get my custom header. I have added expose header in my response and here's the plot twist: When I view the headers from Chrome Inspection Tool or Postman (API tool), it shows all the headers, including my custom one. Here is the fetch code I'm using -
fetch(theUrl, {
method: 'POST',
body: JSON.stringify({
"placeholder": "placeholder"
})
})
.then(function(res) {
console.log(res.headers.get('CUSTOM_HEADER_NAME'));
})
If it makes any difference, this fetch method is called from a function outside the main body of the ReactJS component.
The name of the custom header is Image-Identification-Path, and the header in my response header is Access-Control-Expose-Headers for Image-Identification-Path.
Summary: How do I get my custom header using fetch?
You must configure the server to which the request is sent, such that its response has an Access-Control-Expose-Headers header that has the name of your custom response header.
Otherwise, if your browser doesn’t see the name of your custom header in that Access-Control-Expose-Headers header, it won’t let you access the value of your custom header.
In such a case it’s expected that you’d still be able to see the custom header if you look at the response in Postman or even in your browser devtools.
But just because the browser gets the custom header in the response doesn’t mean the browser will expose it to your frontend JavaScript code.
For cross-origin requests, browsers will only expose that custom response header to your frontend code if that header name is in the Access-Control-Expose-Headers value.
I know this question is old but I ran into this problem yesterday, and the given answer didn't work for me.
The solution I found was given in this article. Basically:
You can’t directly access the headers on the response to a fetch call - you have to iterate through after using the entries() method on the headers.
So, in your particular case you should be able to achieve the goal by using this code:
fetch(theUrl, {
method: 'POST',
body: JSON.stringify({
"placeholder": "placeholder"
})
})
.then(response => {
for (var pair of response.headers.entries()) { // accessing the entries
if (pair[0] === 'CUSTOM_HEADER_NAME') { // key you're looking for, in your case Image-Identification-Path
let imagePath = pair[1]; //// saving that value
}
}
.... })

xhr caching values from getResponseHeader?

I'm running up against a very frustrating bug. I'm not exactly sure what is happening, but I think xhr is doing some kind of cache on the response headers.
My app is using devise_token_auth for the backend authentication service. We're using it with rotating access-tokens, and so I have written a function that runs after every request.
function storeAndGetResponseHeaders(xhr) {
const headersObj = {};
headerKeys.filter((key) => xhr.getResponseHeader(key))
.forEach((key) => {
headersObj[key] = xhr.getResponseHeader(key);
window.sessionStorage.setItem(key, xhr.getResponseHeader(key));
});
return headersObj;
}
where headerKeys is ['access-token', 'client', 'expiry', 'uid', 'token-type']. So any response that has these headers it should save them into sessionStorage and then return them in an object which gets stored within my AJAX service that I wrote and added to every request. We're using rxjs, and this service is just a thin wrapper around it. This is what RxAjax.ajax looks like.
ajax(urlOrRequest) {
const request = typeof urlOrRequest === 'string' ? { url: urlOrRequest } : urlOrRequest;
request.headers = Object.assign({}, this.headers, urlOrRequest.headers);
request.url = `${this.baseUrl}${request.url}`;
return Observable.ajax(request).map(this.afterRequest, this);
}
where this.headers is the stored headers from last request (or the loaded headers from sessionStorage). this.afterRequest is what sets the headers from the response xhr.
My problem is that I'm getting bad values into my headers object (specifically old access tokens). What I've noticed is that when I add a logging statement of headersObj after assignment, sometimes it will have old response headers from a past request. However when I look at the request itself in the dev console Network tab, it doesn't show any of the auth headers in the response headers ('access-token', 'client', etc...). This gets fixed for a little while if I do a hard refresh on the browser, but comes back seemingly inexplicably.
Note we're using rxjs to make our requests, which might be relevant (but I don't think it is the cause of this problem, as I'm trying to read the headers from the original xmlhttprequest object). Thanks!
As Barmar suggested in the comments, it was a caching issue. There may be a bug in the chrome console, where it wasn't showing the cached headers that were on the cached request. Hence even though it looked like there were no auth headers there really were.
It looks like if you're using jQuery you can add the option cache: false to the request in order to prevent caching. Because I'm not, the first thing I did was try adding ?cache=${new Date().toJSON} to each request, which successfully busted the cache and fixed my problem (that is what cache: false in jQuery does).
Our backend is in rails, and so I ended up adding
before_action :set_cache_headers
...
private
def set_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
end
to my application controller. Now no requests are cached by the browser. Not sure if this will be our long term solution or not

Koa cookie returning `undefined`

After a POST request is sent from the browser to the /generate url in the server, I want to create a string and save it as a cookie. When a GET request is later sent from the browser to the /retrieve url in the server, I want to send that string as a response to the client.
Here is what I tried:
routes.js
const Router = require('koa-router')
const router = new Router()
router.post('/generate', function * () {
this.cookies.set('generatedString', 'example')
this.response.body = 'String saved as cookie!'
})
router.get('/retrieve', function * () {
const cookie = this.cookies.get('generatedString')
console.log(cookie) // undefined!
this.response.body = cookie
})
Why does doing this.cookies.get('generatedString') return undefined even though the POST request handler has already run and should have set that cookie? Any help would be appreciated!
EDIT: In case it is of importance, I thought it would be worth mentioning that I am using the fetch API to make the POST and GET requests.
In case it is of importance, I thought it would be worth mentioning that I am using the fetch API to make the POST and GET requests.
The fetch API mentions that "By default, fetch won't send any cookies to the server, resulting in unauthenticated requests if the site relies on maintaining a user session."
If you want fetch to send cookies, you will need to add an option to the request you send out called credentials and set it to a value of include.
Example POST request:
const request = {
method: 'POST',
credentials: 'include',
headers: ...,
body: ...
}
fetch('/generate', request).then(...)
Example GET request:
fetch('/retrieve', { credentials: 'include' }).then(...)

Multiple 'Cookie' headers in a node.js request

I've seen how to make a request with a single cookie, and I've seen how to write a response with multiple cookies, but does anyone know how to write a request in node.js using http module (if possible) with multiple 'Cookie' headers?
So far the only ways I've seen to make a request in node.js involve passing an object as the parameter to a function, which would require having two identical keys.
headers = {
Cookie: firstCookie,
Cookie: secondCookie
}
so wouldn't work.
This is a node.js question, but I'm not extremely confident with http, so I'm not sure if there isn't a way to set two distinct cookies in header. Is it possible to concatenate the two into a single header? Would a request with two separately defined cookies vary from one with a single header containing both?
The 'Cookie' property you added is a direct header in your HTTP request.
You should use only one 'Cookie' header and encode your cookies properly to one valid cookie header string, like that:
var headers = {
Cookie: 'key1=value1; key2=value2'
}
Also, instead of using nodeJS native HTTP client which usually will make you write lots of boilerplate code, I would recommend you to use a much simplified library like Requestify..
This is how you can make an HTTP request with cookies using requestify:
var requestify = require('requestify');
requestify.get('http://example.com/api/resource', {
cookies: {
'key1': 'val1',
'key2': 'val2',
}
})
.then(function(response) {
// Get the response body (JSON parsed or jQuery object for XMLs)
response.getBody();
}
);

Categories

Resources