Aurelia JS post binary data to the server - javascript

I am trying to send a file to the server using aurelia-fetch-client, but get the following error in the browser console. No 'Access-Control-Allow-Origin' header is present on the requested resource., but when I do the same with XMLHttpRequest file is uploaded.
Aurelia Fetch Client configuration and usage code
activate() {
await fetch;
this.http = this.httpClient();
this.http.configure(config => {
config
.useStandardConfiguration()
.withBaseUrl('http://localhost:3000')
});
}
makeRequest(data) {
this.http.fetch('upload', {
headers: {
'Content-Type': 'multipart/form-data'
},
method: 'post',
body: data
});
}

Following the comments here is the answer:
CORS was not enabled on the server, and Ilia suggested the use of the cors-express module if you are using node.
The following resources can be helpful for that:
http://enable-cors.org/server_expressjs.html
https://github.com/expressjs/cors

Related

how to do a post request with jession cookies (fetch/axios)? [duplicate]

I am trying out the new Fetch API but is having trouble with Cookies. Specifically, after a successful login, there is a Cookie header in future requests, but Fetch seems to ignore that headers, and all my requests made with Fetch is unauthorized.
Is it because Fetch is still not ready or Fetch does not work with Cookies?
I build my app with Webpack. I also use Fetch in React Native, which does not have the same issue.
Fetch does not use cookie by default. To enable cookie, do this:
fetch(url, {
credentials: "same-origin"
}).then(...).catch(...);
In addition to #Khanetor's answer, for those who are working with cross-origin requests: credentials: 'include'
Sample JSON fetch request:
fetch(url, {
method: 'GET',
credentials: 'include'
})
.then((response) => response.json())
.then((json) => {
console.log('Gotcha');
}).catch((err) => {
console.log(err);
});
https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
Have just solved. Just two f. days of brutforce
For me the secret was in following:
I called POST /api/auth and see that cookies were successfully received.
Then calling GET /api/users/ with credentials: 'include' and got 401 unauth, because of no cookies were sent with the request.
The KEY is to set credentials: 'include' for the first /api/auth call too.
If you are reading this in 2019, credentials: "same-origin" is the default value.
fetch(url).then
Programmatically overwriting Cookie header in browser side won't work.
In fetch documentation, Note that some names are forbidden. is mentioned. And Cookie happens to be one of the forbidden header names, which cannot be modified programmatically. Take the following code for example:
Executed in the Chrome DevTools console of page https://httpbin.org/, Cookie: 'xxx=yyy' will be ignored, and the browser will always send the value of document.cookie as the cookie if there is one.
If executed on a different origin, no cookie is sent.
fetch('https://httpbin.org/cookies', {
headers: {
Cookie: 'xxx=yyy'
}
}).then(response => response.json())
.then(data => console.log(JSON.stringify(data, null, 2)));
P.S. You can create a sample cookie foo=bar by opening https://httpbin.org/cookies/set/foo/bar in the chrome browser.
See Forbidden header name for details.
Just adding to the correct answers here for .net webapi2 users.
If you are using cors because your client site is served from a different address as your webapi then you need to also include SupportsCredentials=true on the server side configuration.
// Access-Control-Allow-Origin
// https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
This works for me:
import Cookies from 'universal-cookie';
const cookies = new Cookies();
function headers(set_cookie=false) {
let headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}
Then build your call:
export function fetchTests(user_id) {
return function (dispatch) {
let data = {
method: 'POST',
credentials: 'same-origin',
mode: 'same-origin',
body: JSON.stringify({
user_id: user_id
}),
headers: headers(true)
};
return fetch('/api/v1/tests/listing/', data)
.then(response => response.json())
.then(json => dispatch(receiveTests(json)));
};
}
My issue was my cookie was set on a specific URL path (e.g., /auth), but I was fetching to a different path. I needed to set my cookie's path to /.
If it still doesn't work for you after fixing the credentials.
I also was using the :
credentials: "same-origin"
and it used to work, then it didn't anymore suddenly, after digging much I realized that I had change my website url to http://192.168.1.100 to test it in LAN, and that was the url which was being used to send the request, even though I was on http://localhost:3000.
So in conclusion, be sure that the domain of the page matches the domain of the fetch url.

How To Access Fetch Request Cookies Value in JS [duplicate]

I am trying out the new Fetch API but is having trouble with Cookies. Specifically, after a successful login, there is a Cookie header in future requests, but Fetch seems to ignore that headers, and all my requests made with Fetch is unauthorized.
Is it because Fetch is still not ready or Fetch does not work with Cookies?
I build my app with Webpack. I also use Fetch in React Native, which does not have the same issue.
Fetch does not use cookie by default. To enable cookie, do this:
fetch(url, {
credentials: "same-origin"
}).then(...).catch(...);
In addition to #Khanetor's answer, for those who are working with cross-origin requests: credentials: 'include'
Sample JSON fetch request:
fetch(url, {
method: 'GET',
credentials: 'include'
})
.then((response) => response.json())
.then((json) => {
console.log('Gotcha');
}).catch((err) => {
console.log(err);
});
https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
Have just solved. Just two f. days of brutforce
For me the secret was in following:
I called POST /api/auth and see that cookies were successfully received.
Then calling GET /api/users/ with credentials: 'include' and got 401 unauth, because of no cookies were sent with the request.
The KEY is to set credentials: 'include' for the first /api/auth call too.
If you are reading this in 2019, credentials: "same-origin" is the default value.
fetch(url).then
Programmatically overwriting Cookie header in browser side won't work.
In fetch documentation, Note that some names are forbidden. is mentioned. And Cookie happens to be one of the forbidden header names, which cannot be modified programmatically. Take the following code for example:
Executed in the Chrome DevTools console of page https://httpbin.org/, Cookie: 'xxx=yyy' will be ignored, and the browser will always send the value of document.cookie as the cookie if there is one.
If executed on a different origin, no cookie is sent.
fetch('https://httpbin.org/cookies', {
headers: {
Cookie: 'xxx=yyy'
}
}).then(response => response.json())
.then(data => console.log(JSON.stringify(data, null, 2)));
P.S. You can create a sample cookie foo=bar by opening https://httpbin.org/cookies/set/foo/bar in the chrome browser.
See Forbidden header name for details.
Just adding to the correct answers here for .net webapi2 users.
If you are using cors because your client site is served from a different address as your webapi then you need to also include SupportsCredentials=true on the server side configuration.
// Access-Control-Allow-Origin
// https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
This works for me:
import Cookies from 'universal-cookie';
const cookies = new Cookies();
function headers(set_cookie=false) {
let headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}
Then build your call:
export function fetchTests(user_id) {
return function (dispatch) {
let data = {
method: 'POST',
credentials: 'same-origin',
mode: 'same-origin',
body: JSON.stringify({
user_id: user_id
}),
headers: headers(true)
};
return fetch('/api/v1/tests/listing/', data)
.then(response => response.json())
.then(json => dispatch(receiveTests(json)));
};
}
My issue was my cookie was set on a specific URL path (e.g., /auth), but I was fetching to a different path. I needed to set my cookie's path to /.
If it still doesn't work for you after fixing the credentials.
I also was using the :
credentials: "same-origin"
and it used to work, then it didn't anymore suddenly, after digging much I realized that I had change my website url to http://192.168.1.100 to test it in LAN, and that was the url which was being used to send the request, even though I was on http://localhost:3000.
So in conclusion, be sure that the domain of the page matches the domain of the fetch url.

CORS policy problem in react js client side

I created a Formik login form and call to react js fetch method. Add cors in web api end and successfully run in Postman and jquery. How to call "token_type": "bearer", through react js? cors is also enabled in web api and also generate Token successfully. How to call this url https://localhost:44323/token through react js?
My code is
onSubmit={(values) => {
fetch('https://localhost:44323/token', {
method: 'POST',
header: { 'Content-type': 'application/json,multipart/form-data' },
data: JSON.stringify(values)
})
.then(r => r.json())
.then(res => {
console.log(res)
});
}}>
Error messages
The root cause of the problem can be found in the following error message shown:
"Access to fetch at https://localhost:44323/token from origin http://localhost:3000 has been blocked by CORS policy. No Access-Control-Allow-Origin header is present on the requested resource ...."
How to fix the problem?
The problem can be fixed in these ways:
1. Allow the origin (http://localhost:3000) on the server (Recommended)
This can be done by adding the following header to HTTP response on the server side:
Access-Control-Allow-Origin: http://localhost:3000
2. Send Fetch request in the 'no-cors' mode
This can be done by updating the fetch request as follows:
fetch( 'https://localhost:44323/token',
{
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}
)
.then(response => {
// Code for processing the response
}
)
.catch((error) => {
// Code for handling the error
}
)
More information:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

How to set POST request via axios on REST API?

How to set POST request via axios on REST API?
Headers
I see that get uncorrect headers, but I don't understand, why?
Also, I often come across the fact that the documentation of the axios simply doesn't work.
Example get GET request, it works:
Dynamic host in axios
const configAxios = {
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Access-Control-Allow-Origin': '*',
},
};
const data = JSON.stringify({
cardData: this.cardData.brand,
});
axios.post('api/products', {
data,
},
configAxios,
)
.then((req) => {
this.data = req.data;
console.log(req);
})
.catch((err) => {
console.warn('error during http call', err);
});
This is necessary to get the host API:
p.s.: this will be work only in this way.
const baseURL = 'http://localhost:8080';
if (typeof baseURL !== 'undefined') {
Vue.axios.defaults.baseURL = baseURL;
}
axios version: e.g.: v0.16.2
Environment: e.g.: node v8.9.4, chrome 64.0.3282.119, Ubuntu 16.04
Symfony 4.0.4
Vue.js 2.4.2
vue-axios 2.0.2
If the API and the client are on separate domain names, you need to properly configure CORS headers to allow the client contacting the server. You also need to whitelist the authorized headers.
With API Platform and Symfony, you can easily do it using NelmioCorsBundle. If you use Symfony 4/Flex, run:
$ composer req cors
The package will be automatically installed and properly configured. `Content-Type] will even be whitelisted.

node 'fs' and 'request' to upload file via REST API

I am trying to use a REST API to upload a file. I have a function that works for every other type of request, but this one (which uploads a file) doesn't want to work:
var createItem = function ()
{
request.post(
{
url:browser.params.baseRestUrl + 'repositories/Samples/items',
auth: browser.params.auth,
body: fs.createReadStream(filepath),
form:
{
headers: {'content-type': 'application/octet-stream',
'Content-Disposition': 'attachment; filename="oneHourSally3.fmw"',
'Accept': 'application/json'
},
}
},
function(e,r,user){ console.log("Status code of createItem('oneHourSally'): " + r.statusCode);});
};
This returns a http 415 (unsupported media type) error.
Usually that error implies that the server is only willing to accept a specific Content-Type. You're specifying application/octet-stream and the server tells you it doesn't accept that. Consult the documentation of the API to figure out what is supported, or contact the authors of the API via a support channel.

Categories

Resources