I'm sending data to the server using JSON and post method, but I can't read the response from the server. Here's my code:
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://staging.smartenupcs.com/api/v1/licenses/create", true);
xhr.setRequestHeader("Smartenup-API-KEY", "webflow.c407d56c5ab23115af0075+DzDMrMtWZENCoct9Pa7DUA54mIgP8c9o");
var jsonStr = JSON.stringify({
"first_name": "Bla",
"last_name": "Blabla",
"email": "bla#gmail.com",
"product_name": "webflow_essentials",
"order_id": 21811,
"voucher": null
});
xhr.send(jsonStr);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var myObj = JSON.parse(xhr.responseText);
alert(myObj);
}
};
I tried many options but no success.
I hope someone can help, thank you in advance
There are no issues with the code.
The issue is with Cross-Origin Requests. You seems to be hitting API from domain other than staging.smartenupcs.com most probably localhost.
Just add cross-origin headers to server and it will work.
PS: It will work without cross-origin headers when your frontend code and api are hosted on same domain.
Please check at Server side for Access-Control-Allow-Origin header. Also check for OPTIONS preflight request of that api/action. After that check for api response status and your response checking condition.
I would recommend using fetch API instead of the XMLHttpRequest object.
function postData(url = `UR_URL_HERE`, data = {}) {
// Default options are marked with *
return fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, cors, *same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
// "Content-Type": "application/x-www-form-urlencoded",
},
redirect: "follow", // manual, *follow, error
referrer: "no-referrer", // no-referrer, *client
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
.then(response => response.json()); // parses response to JSON
}
Related
Seems like a simple issue but everywhere else suggested adding "application/json" in 'headers' which I have tried.
'Accept'and 'Content-Type' are both "application/json".
Also tried both json and stringfy 'Body' but keep getting 415 on Chrome extension JavaScript.
textArraySample = ["sample","sample2"];
var serverUrl = "https://webappcontentnotification.azurewebsites.net/api/ContentUpload";
const body={
"textbatch":textArraySample,
"userId": userId,
"url": window.location.href
}
let result =
fetch(serverUrl, {
method: 'POST',
mode: "no-cors",
headers: {
'Accept': "application/json",
'Content-Type': "application/json"
},
body: JSON.stringify(body)
})
.then(response => {
console.log('response:', response);
})
.catch((error) => {
console.log('Error:', error);
});
Update: seems like "Content-Type" is not correctly set
Did not see this mentioned somewhere else.
The root cause is that "Content-Type" cannot be set to "application/json" while using "Mode: no-cors".
link here
mode: "no-cors" only allows a limited set of headers in the request:
Accept
Accept-Language
Content-Language
Content-Type with a value of application/x-www-form-urlencoded, multipart/form-data, or text/plain
I am attempting to make an api get request using JS's built in XMLHttpRequest system. I am not sure why this function fails to work.
function updateStats(username){
const request = new XMLHttpRequest;
var url = "https://pitpanda.rocks/api/players/" + username;
request.open("GET", url);
request.send();
request.onload = (e) => {
return request.response;
}
}
My code is running on CodePen right now https://codepen.io/casperqf/pen/NWXGeqa
I recommend using fetch. Allows you to set the method and some other values.
Can do with fetch and not with XHR:
You can use the API with the request and response objects.
You can perform no-cors requests, getting a response from a server that doesn't implement CORS. You can't access the response body directly from JavaScript.
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
function updateStats(username, stats){
postData('https://pitpanda.rocks/api/players/' + username, { stats: stats })
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
}
updateStats('otik', 123);
I am trying to build a frontend interface to communicate with an API service, I am using HTML,CSS & JavaScript. I am using async function / await fetch to call the API and response.jsom to retrieve the Json data from the response, now I have to add X-Authorization:Bearer Token '.....' to the header, how can I do that with JavaScript?
thanx for help
Add your token inside the header, here is an example, call this postData function anywhere from your application, you can add it in a common place
Also check
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
this for the detailed explanation
// Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
let token = "Get your token here, Store it in local storage and read it from local storage is a better method"
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
"X-Authorization":Bearer Token '.....' // Here you can add your token
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData('https://example.com/answer', { answer: 42 })
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
I have built an API and app that uses that API. When I POST method via Postman, it works fine, but when I try fetching it via app, I get a bad request 400 status response. What am I doing wrong?
Here is my JavaScript code:
const myForm = document.getElementById('loginForm');
myForm.addEventListener('submit', function(e) {
e.preventDefault();
const url = 'https://thawing-peak-69345.herokuapp.com/api/auth';
const myHeaders = new Headers();
myHeaders.append('Accept', 'application/json, text/html, */* ');
myHeaders.append('Content-Type', 'application/json, charset=utf-8')
const formData = {
email: this.email.value,
password: this.password.value
};
console.log(formData);
const fetchOptions = {
method: 'POST',
mode: 'no-cors',
cache: 'no-cache',
headers: myHeaders,
body: JSON.stringify(formData)
};
fetch(url, fetchOptions)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.log(err))
})
Request
Response
Headers request:
Headers response:
You said:
mode: 'no-cors',
This is a declaration that you are not doing anything that requires permission be granted with CORS. If you try to do anything that does need permission, it will be silently ignored.
myHeaders.append( 'Content-Type', 'application/json, charset=utf-8')
Setting the Content-Type header to a value not supported by the HTML form element's type attribute requires permission from CORS. application/json is not such a value.
Consequently, the request is sent as text/plain.
Since it isn't marked as being JSON, the server throws a 400 error.
You need to:
Remove mode: 'no-cors',
Make sure that the service you are making the request to will use CORS to grant you permission (or to use a service on the same origin as the request).
On making request like that:
return fetch(
'http://localhost:8000/login',
{ method: 'POST',
headers: new Headers(
{"Content-Type": "application/json",
"Accept":"application/json"}
),
body: JSON.stringify(
{'name': 'Tom', 'password': 'Soyer'}
)
}
).then( response => { console.log(response);})
.catch(err => console.log(err))
request running with method OPTIONS instead POST.
Only on adding mode: 'no-cors' request become POST:
return fetch(
'http://localhost:8000/login',
{ method: 'POST',
mode: 'no-cors',
headers: new Headers(
{"Content-Type": "application/json",
"Accept":"application/json"}
),
body: JSON.stringify(
{'name': 'Tom', 'password': 'Soyer'}
)
}
).then( response => { console.log(response);})
.catch(err => console.log(err))
but response not ok than (even if network response status is 200): {type: "opaque", url: "", status: 0, ok: false, statusText: ""…}
I suppose it because
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded multipart/form-data text/plain
described here https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Is any way bring to live POST json data with fetch?
The custom Content-Type header you're sending causes your request to be preflighted, which means an OPTIONS request, containing some metadata about the POST request that is about to be dispatched, will be sent before the actual POST request.
Your server needs to be prepared to deal with this OPTIONS request. You haven't specified what the server is written in, but with express for example, you can register a middleware that intercepts all 'OPTIONS' requests, sets the Access-Control-Allow-Origin: * and Access-Control-Allow-Headers: Content-Type headers, and responds with 200.
If it is possible for you to make the request using a 'Content-Type': 'text/plain' header, that would solve your problem. Alternatively you could use something that bypasses XHR entirely, like JSONP.
When using non-cors, all headers must be valid simple-headers. The only valid values for the content-type header that qualifies as a simple-header is:
headers: [
['Content-Type', 'application/x-www-form-urlencoded'],
['Content-Type', 'multipart/form-data'],
['Content-Type', 'text/plain'],
]
Exceptions with contingencies:
headers: [
['Content-Type', 'application/csp-report'],
['Content-Type', 'application/expect-ct-report+json'],
['Content-Type', 'application/xss-auditor-report'],
['Content-Type', 'application/ocsp-request'],
]
simple-header
cors-protocol-exceptions
If you are trying to call an api and getting stuck with this in your react app you can add a proxy to the server and the cors error will get removed
just add this line at the package.json
"proxy":"url-to-your-server",