The post request to the Django Rest API framework works via Postman when the appropriate parameters are filled in the 'body' section. But the same does not work with the following JavaScript code:
var data = {emp_id:50,emp_name:'test',password:'pass123'};
fetch('http://127.0.0.1:8000/signup/',{
method:"POST",
body: JSON.stringify(data),
mode:"no-cors",
headers: {
"Content-Type": "application/json",
// "Content-Type": "application/x-www-form-urlencoded",
},
})
.then(response => response.json());
The following is the def that handles the POST request in the views.py of the REST-API:
#api_view(['GET', 'POST', ])
def signup(request):
serializer = employeeSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I'm new to this, can anyone tell me why the JavaScript code won't work?
EDIT:
The error which the browser console shows is:
POST http://127.0.0.1:8000/signup/ 415 (Unsupported Media Type)
The issue is that by using no-cors mode you constrain yourself to using simple requests, which in turn cannot have content-type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain. In fact, if you look at the headers sent by the browser with your request, you'll see that the content type changes from application/json to text/plain - hence the error.
To fix your issue: remove no-cors mode and add cors headers to responses in your django app. You can use django-cors-headers for that.
Also, you have no issues with postman because it does not care about same-origin policy.
Try change headers to
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
The accept header is used by to determine what format to sent the data back to the client in the response, guess it might be needed
I found the solution here : https://learning.postman.com/docs/sending-requests/generate-code-snippets/#generating-code-snippets-in-postman
with postman you can see the code of headers sent on the request on many languages (Node Axios, javascript fetch ...), then just copy paste the headers and all the data sent by postman to your app
Related
In a bit of a pickle at the moment , I could do a postman request like that and I get my data response back :
URL : https://hiddenurlforexample.com
Authorization : Bearer XXXXXXXX-XXXX-XXXX-XXXX
When I do it on Axios on my website though I get a 401 CORS error. Any idea what the difference is ? This is how my axios request looks like :
axios
.request({
url: 'test/url',
method: 'get',
baseURL: 'https://hiddenurlforexample.com',
headers: {
"Access-Control-Allow-Origin" : "*",
"Content-type": "Application/json",
"Authorization": "Bearer XXXXXXXX-XXXX-XXXX-XXXX"
}
})
.then(response => {
console.log(response.data)
})
.catch(function (error) {
console.log(error)
})
I am a Frontend Developer, I have been told that there was nothing to do in the backend .
What Chris G said, and next to that Postman ignores the CORS validation because it is a dev tool.
Your backend server should return the correct CORS headers. While developing you could go with a wildcard for the CORS headers but it's highly recommended to add the specific domain you're calling the backend from (i.e. the domain of your website).
Also note that the CORS headers are returned via an OPTIONS call, again, your backend should support that. What backend are you running?
I am using axios in reactjs application. My code is like below
axios.post('/api/addresses/upload/',formData,config)
.then(function (response) {
})
.catch(error => {
});
I did not use any console.log() statement any where but I am getting below error in console.
How this error printed in console ?
Try by setting the header for the axios request,
The HyperText Transfer Protocol (HTTP) 422 Unprocessable Entity response status code indicates that the server understands the content type of the request entity, and the syntax of the request entity is correct, but it was unable to process the contained instructions.
May be you will be missing some of your required fields which is mandatory while processing the operations like insertion or updation of a record in your Database. May be you can have the look at it. If everything works well then try the following settings to the header of your request.
If your submitting the form with files then use the header's content-type as
'multipart/form-data',
without files means then set the content-type as 'application/x-www-form-urlencoded',
If you need to post the json means then set the content-type as 'application/json' and "Accept: 'application/json'"
If any cors error occurs then use 'crossDomain': true
var formData = new FormData();
axios.post('/api/addresses/upload/', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
I'm building a SignUp form and have the following API call to POST the form:
const request = new Request('http://localhost:4300/auth/', {
method: 'POST',
headers: new Headers({
'Accept' : 'application/json',
'Content-Type' : 'application/json',
}),
body: JSON.stringify({ user: data })
});
fetch(request).then(response => {
console.log(response);
const auth = response.headers.get('Authorization');
console.log(auth)
});
The problem is response.headers.get('Authorization') is returning as null. Even though if I look at Chrome's Network XHR request I see the Response Headers being sent by the API server.
Why is React not providing me with response.headers via the request above?
Thanks
The value of the Access-Control-Expose-Headers response header for the response from http://localhost:4300/auth/ must include "Authorization" if you want your requesting frontend JavaScript code to be allowed to access the Authorization response header value.
If the response includes no value for the Access-Control-Expose-Headers header, the only response headers browsers will let you access from client-side JavaScript in your web app are Cache-Control,
Content-Language,
Content-Type,
Expires,
Last-Modified
and
Pragma.
See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name for the spec.
I are trying to fetch data from our API. The API has enabled CORS support and returns the below response to the OPTIONS request:
Access-Control-Request-Headers:content-type
Access-Control-Allow-Origin:*
The API doesn't allow 'Content-type' anything other than 'application/json'.
Using this limitation, I am trying to use the fetch method of React-Native to get the data.
Method 1 (no-cors):
{
method: 'POST',
mode: "no-cors",
headers: {
'content-type': 'application/json'
}
With this method, the browser automatically sends the content-type as 'text/plain'. I assume this is because CORS allow just one of the three headers by default. However, since the server doesn't support this content-type, it returns an error back for unsupported content type.
Method 2 (with cors or with nothing):
{
method: 'POST',
mode: "cors", // or without this line
redirect: 'follow',
headers: {
'content-type': 'application/json'
}
}
...
.then(response => console.log(response))
In this scenario, using Chrome's F12 network tool, I can see the server returning data : the first request to the server is a fetch for OPTIONS. To this, the server replies back with an empty object along with the above headers set. The next call is the actual POST API call, to which the server responds back with a proper JSON response containing some data. However, the response which is getting on the console via my code is {}. I assume this is because the react's fetch API is returning back the response of the OPTIONS call instead of the actual POST call.
Is there any way to ignore the response of the OPTIONS request and get the then method to process the response of the subsequent request?
The immediate problem you’re hitting is, your code as currently written expects the response to be JSON but the response is actually a Promise that you need to handle to get the JSON.
So you need to instead do something like this:
fetch("https://example.com")
.then(response => response.json())
.then(jsondata => console.log(jsondata))
having a problem with getting data back from database. I am trying my best to explain the problem.
1.If I leave "mode":"no-cors" inside the code below, then I can get data back from server with Postman, but not with from my own server. Thinking it has to be my client side error
When I remove "mode":"no-cors" then I am getting 2 errors:
-Fetch API cannot load http://localhost:3000/. Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
-Uncaught (in promise) TypeError: Failed to fetch
Quick Browsing suggested to put in the "mode":"no-cors" which fixed this error, but it does not feel right thing to do.
So I thought maybe somebody has a suggestion how to approach this problem.
Really hope I was clear enough, but pretty sure I am not giving clear explanation here :S
function send(){
var myVar = {"id" : 1};
console.log("tuleb siia", document.getElementById('saada').value);
fetch("http://localhost:3000", {
method: "POST",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "text/plain"
},//"mode" : "no-cors",
body: JSON.stringify(myVar)
//body: {"id" : document.getElementById('saada').value}
}).then(function(muutuja){
document.getElementById('väljund').innerHTML = JSON.stringify(muutuja);
});
}
Adding mode:'no-cors' to the request header guarantees that no response will be available in the response
Adding a "non standard" header, line 'access-control-allow-origin' will trigger a OPTIONS preflight request, which your server must handle correctly in order for the POST request to even be sent
You're also doing fetch wrong ... fetch returns a "promise" for a Response object which has promise creators for json, text, etc. depending on the content type...
In short, if your server side handles CORS correctly (which from your comment suggests it does) the following should work
function send(){
var myVar = {"id" : 1};
console.log("tuleb siia", document.getElementById('saada').value);
fetch("http://localhost:3000", {
method: "POST",
headers: {
"Content-Type": "text/plain"
},
body: JSON.stringify(myVar)
}).then(function(response) {
return response.json();
}).then(function(muutuja){
document.getElementById('väljund').innerHTML = JSON.stringify(muutuja);
});
}
however, since your code isn't really interested in JSON (it stringifies the object after all) - it's simpler to do
function send(){
var myVar = {"id" : 1};
console.log("tuleb siia", document.getElementById('saada').value);
fetch("http://localhost:3000", {
method: "POST",
headers: {
"Content-Type": "text/plain"
},
body: JSON.stringify(myVar)
}).then(function(response) {
return response.text();
}).then(function(muutuja){
document.getElementById('väljund').innerHTML = muutuja;
});
}
In my case, the problem was the protocol. I was trying to call a script url with http instead of https.
try this
await fetch(url, {
mode: 'no-cors'
})
See mozilla.org's write-up on how CORS works.
You'll need your server to send back the proper response headers, something like:
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
Bear in mind you can use "*" for Access-Control-Allow-Origin that will only work if you're trying to pass Authentication data. In that case, you need to explicitly list the origin domains you want to allow. To allow multiple domains, see this post
you can use solutions without adding "Access-Control-Allow-Origin": "*", if your server is already using Proxy gateway this issue will not happen because the front and backend will be route in the same IP and port in client side but for development, you need one of this three solution if you don't need extra code
1- simulate the real environment by using a proxy server and configure the front and backend in the same port
2- if you using Chrome you can use the extension called Allow-Control-Allow-Origin: * it will help you to avoid this problem
3- you can use the code but some browsers versions may not support that so try to use one of the previous solutions
the best solution is using a proxy like ngnix its easy to configure and it will simulate the real situation of the production deployment
Sometimes, please check your port number. If localhost port number is mismatch, you will get the same error as well.
I was getting this error and realized my server.js wasn't running.