Axios won't send cookie, Ajax (xhrFields) does just fine - javascript

Using Axios
export function sendAll() {
return (dispatch) => {
dispatch(requestData());
return axios({
method: 'POST',
url: `${C.API_SERVER.BASEURL}/notification/sendAll`,
data: {prop: 'val'},
// responseType: 'json',
headers: {
'Content-Type': 'application/json'
},
withCredentials: true
}).then((response) => {
dispatch(receiveData(response));
}).catch((response) => {
dispatch(receiveError(response));
// dispatch(pushState(null, '/error'));
})
}
};
Result using Axios
Using $.ajax
$.ajax({
url: " http://local.example.com:3001/api/notification/sendAll",
method: "post",
data: {},
crossDomain: true,
xhrFields: {
withCredentials: true
}
})
Result using $.ajax
I am unable to force Axios to send a POST when trying to attach data to POST (cookie doesnt get sent either way).
My server setup (express):
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", `${C.PROTOCOL}://${C.DOMAIN}:${C.PORT}`);
res.header("Access-Control-Request-Headers", "*");
res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
I do not have a OPTIONS route defined. I want Axios to send POST with cookie.
router.post('/notification/sendAll', function (req, res, next) {
res.sendStatus(204);
// ...
});

I was facing a similar issue. Making a get/post request through Axios did not sent the same headers as a straight XHR request.
Then I just added the following just after the Axios require statement:
axios.defaults.withCredentials = true;
After that Axios started sending my cookie like the regular XHR request did.

Working example using Danielo515's answer:
import * as axios from 'axios';
axios.defaults.withCredentials = true;
export function getAll() {
const url = 'https://example.com';
return axios.get(url);
}

Related

CORS origin always undefined when fetching data

Using this server configuration
import Cors from 'cors';
const cors = Cors({
methods: ['GET', 'POST', 'HEAD'],
allowedHeaders: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-Api-Authorize, X-Authorize',
credentials: true,
origin: (origin, callback) => {
console.log("*** TESTING", origin);
return callback(null, true); // debug, otherwise nothing works
},
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
});
const applyCors = async (req, res) => new Promise((resolve, reject) => {
cors(req, res, (result) => {
if (result instanceof Error) {
reject(result);
} else {
resolve(result);
}
});
});
export const apiMiddleware = handler => async (req, res) => {
await applyCors(req, res);
// ... req is extended with utils
return handler(req, res);
};
And a client fetch request like
const response = await fetch(`/api/data`, {
credentials: 'same-origin', // also tried "include"
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-Api-Authorize': 'secret'
},
method: 'GET'
});
The server console.log always prints
*** TESTING undefined
When inspecting the request, I see the X-Api-Authorize header, but not Origin. What's missing?
fetch(`/api/data`
That's a relative URL, so you are making a same-origin request.
The origin header is only included in cross-origin requests.
(That's a simplification, as jub0bs points out, there are other times it will be included, but your code doesn't meet any of those conditions).

axios set custom cookies

Im trying to set a custom cookie, for axios requests. But it's not working.
Thats my code
const axios = require('axios');
axios.defaults.withCredentials = true;
const client = axios.create({
withCredentials: true
});
let url = 'https://google.de';
client
.get(url, {
headers: {
Cookie: [
'cookie1=value;'
],
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
}
})
.then(res => {
console.log(res.headers['set-cookie']); // Im getting "undefined"
})
.catch(err => console.error(err));
i tried different ways, but have no luck. maybee any one know how i can set custom cookies in axios? or recommend a better library to do that..

Why isn't my Fetch request sending custom headers in React-Native?

I am calling a fetch request akin to this.
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: new Headers({
'custom-header': 'custom header value'
})
}
)
.then(res=>{
/* code */
})
.catch(err=>{
/* code */
})
But it seems that the header is not being sent to the server. The server runs on Node.js, and I am attempting to reach it with React-Native.
I have allowed "access-control-allow-origin": "*" on the server, but to no avail.
I can also reach other endpoints on the server that don't require any headers.
And lastly, I have set the headers with both new Headers() and as an object.
What exactly am I missing to allow the headers to be sent? Is there a way to see exactly what is going on with my request in react-native?
It works in postman just fine.
EDIT:
I am using the cors middleware in my server.
app.use(cors())
appConfig.init(app);
Can you add these lines before using routes and try?
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, custom-header"
);
res.header("Access-Control-Expose-Headers", "custom-header");
next();
});
And if you are using express cors middleware, you can add allowedHeaders and exposedHeaders options.
https://github.com/expressjs/cors#configuration-options
note if these configuration replaces the default headers, you may need to add the default headers to the options.
app.use(
cors({
exposedHeaders: ["custom-header"],
allowedHeaders: ["custom-header"]
})
);
Lastly you had better to use fetch api like this to send headers:
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: {
"custom-header": "custom header value"
}
}
)
.then(res => {
/* code */
})
.catch(err => {
/* code */
})
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Be sure,you added the header in:
res.header(
"Access-Control-Allow-Headers",
"Your_OWN_header,...."
);

Send JSON data to another server (PayU) using express and angular

I am trying to make a payment application with PayU and don't know how can I send JSON data to PayU server. How I can do that?? Please help me or give me some advice. I should pass the information (from body: {...} below) POST to https://secure.snd.payu.com/api/v2_1/orders
Data which I should send to PayU (body: {...})
userFactory.paypalPayment = function(payment) {
return $http({
method: 'POST',
url: "/paynow",
headers: {
'Content-Type': 'application/json'
},
body: {
"notifyUrl": "https://your.eshop.com/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "145227",
"description": "Toyota",
"currencyCode": "USD",
"totalAmount": "12",
"products":{
"name": "Wireless mouse",
"unitPrice": "15000",
"quantity": "1"
},
}
});
}
return userFactory
app.js (ExpressJS)
router.post('/paynow', function(req, res){
res.setHeader('Content-type', 'application/json; charset=utf-8');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.json({ success: true})
})
controller
app.payment = function(payment){
User.paypalPayment().then(function(data){
console.log(data.data)
if(data.data.success) {
$window.location = 'https://secure.snd.payu.com/api/v2_1/orders'
} else {
console.log('Wrong way')
}
})
}
In order to make HTTP request to another server from NodeJS application you can use request module (or request-promise-native if you prefer promises). Code might look like this:
router.post('/paynow', function(req, res){
// your code here
request({
method: 'POST',
json: { body: req.body },
uri: 'https://secure.snd.payu.com/api/v2_1/orders',
headers: { "Content-Type": "application/json" },
(err, response, body) => {
// Callback - you can check response.statusCode here or get body of the response.
// Now you can send response to user.
}
});
});

Response for preflight has invalid HTTP status code 404 angular js

I am trying to prepare a Delete request in AngularJS to a nodeJS local server:
this.deleteMusician = function(id) {
$http({
url: 'http://localhost:3000/musicians/' + id,
method: "DELETE",
data: {}
//processData: false,
//headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
console.log(data);
}).error(function (data, status, headers, config) {
console.log(data);
});
};
And my nodeJS route looks like this:
app.delete('/musicians/:id', musicians.delete);
The same request via PostMan works, but on Google Chrome i get:
OPTIONS http://localhost:3000/musicians/5628eacaa972a6c5154e4162 404 (Not Found)
XMLHttpRequest cannot load http://localhost:3000/musicians/5628eacaa972a6c5154e4162. Response for preflight has invalid HTTP status code 404
CORS is enabled:
var allowCrossDomain = function(req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
};
app.use(allowCrossDomain);
You will need to configure your node server to expect options method too.Check this other answer
so:
app.options('/musicians/:id', optionsCB);
and:
exports.optionsCB = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
next();
}

Categories