The fetch() API is not POSTing this JSON body.
var j = {
"addressee": "James"
};
return fetch('http://requestb.in/blahblahblah', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
},
body: JSON.stringify(j)
})
There is absolutely no request body showing up in RequestBin for this. What could be happening to the body? Debugging JSON.stringify(j) shows that it is indeed formatting the body correctly.
Turns out the fetch() API was sending an OPTIONS preflight request, to see the CORS configuration on the server. Removing the headers in my fetch() request stopped this from happening.
I solved this by changing
<input type="submit" onSubmit={()=>{}}/>
to
<button type="button" onClick={this.someFunction}>Submit</button>
Don't know why, but while using ReactJS developed app in Firefox, this has always worked for me. Without this, the browser simply did not fire the POST request(could not see it in the Developer Options:Network Tab).
Using this remedy, it just worked without doing any other change, started seeing the POST requests.
Related
I would like to test the api of an application, I've got a token from the developer, but I'm getting an error 'cy.request() failed on:
https://******************************
The response we received from your web server was:
406: Not Acceptable
This was considered a failure because the status code was not 2xx or 3xx.'
This is the code that I used:
describe('API Test', () => {
const token = 'your_token_here';
it('Should make a GET request with a Bearer token and avoid 406 error', () => {
cy.request({
method: 'GET',
url: 'https://your-api.com/endpoint',
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
}).then((response) => {
expect(response.status).to.eq(200);
expect(response.body).to.be.an('object');
});
});
});
I tried with 'Accept': 'application/json' and 'Content-Type': 'application/json', but it didn't help.
the Content-type header is used to indicate the original media type of the resource.
Here since you are sending a GET request content-type does not matter.
the Accept header is used by the sender of the request(browser) to specify response media types that are acceptable. So here in your case maybe the type of the response is not application/json that's why you are gettin an
406: Not Acceptable
I found also in this source that in some cases, the server could be responsible for the 406 Error since it's the network object producing the error. Perhaps the server is misconfigured and can't handle the request correctly. Maybe it's a traffic routing issue.
so try your REQUEST without any header and if the 406 still occurs you are sure that it is from ther server and that your REQUEST is OK.
Possibly I'm still not completely understanding all the ins and outs of browser security, but i think what I'm trying to achieve is relatively simple.
I have a page served 100% over HTTPS, I'm using basic auth, with the username & password being held by the browser and (should) be sent with every request from there onwards.
I have added the credentials: 'same-origin' to the fetch function call and for GET requests its included. but the same code path with a POST request does not include the header in the request.
fetch("/center/57023368c4d6931600216494", {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
credentials: "same-origin",
method: "GET"
})
fetch("/users/find", {
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
credentials: "same-origin",
method: "POST",
body: "{\"center\":\"US testing\"}"
})
I don't think this is a CORS issue since everything is talking to the same domain. Ive tried expanding to credentials: 'include' but no difference. And I've seen the problem in both Safari & Chrome.
There seems to be little or no feedback so I'm really stuck as to weather this is a spec / implementation issue or a browser issue or a "your not using the code correctly" issue, any help appreciated
I wrote a pretty basic API using a SilverStripe module (here) and while building it I was testing using Postman and Advanced REST Client chrome extension so I know the endpoints work.
Now when trying to reach the endpoints (POST json) the API is telling me that required values aren't set. I'm did a little bit of digging and compared the request headers from Postman to the ones from Angular using Firebug. The only noticeable discrepancy is that in Postman the header for Content-Type is:
"application/json"
and for Angular it's:
"application/json; charset=UTF-8"
Here's the code for the Angular POST (pretty basic):
notebookFactory.addNotebook = function(title) {
var notebook = "Testing Title 23!";
var message = {
Title: notebook
};
return $http({
url: 'api/notebook',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: message
});
};
The API error says: "The JSON property Title is required"
Is this something that could make a difference? I've tried adding charset=UTF-8 to the end of the Content-Type in Postman and receive the same error. Is there any way to remove the charset from the Angular POST header?
Let me know if you need any more info and thanks in advance!
This was a small issue with the code for handling json in the RESTful API module.
The developer has made the fix already and can be referenced here: https://github.com/pstaender/silverstripe-restful-api/issues/1
Using restangular and the stub hub api. I can hit this API on the firefox restclient and get a response body back with all the JSON data.
But in my app, I get a 200 but no response body... the content length even says something's there
albeit the api says you just need GET/URI endpoint and Authorization: Bearer {token}
Here's my restangular config
'use strict';
angular.module('myapp')
.config(['RestangularProvider', function(RestangularProvider){
RestangularProvider.setBaseUrl('https://api.stubhub.com/');
RestangularProvider.setDefaultHeaders({
Accept: 'application/json',
Authorization: 'Bearer 198u2190832190831432742(notreallymytoken)'
});
RestangularProvider.setDefaultHttpFields({
withCredentials: false
});
}]);
and here's my controller
$scope.searchEvents = function(){
Restangular.one('search/catalog/events/v2?title="san francisco"').get().then(function(response){
$scope.searchResponse = response;
}, function(response){
console.log("something went wrong");
})
}
How can I begin to debug? I want to keep using restangular so hopefully I can get around this somehow.
I figured out what the problem was and could be in your case too.
The Content-Type for your response would have probably been something like application/javascript and NOT application/json.
Which is why it is not caught by Restangular but by browser or REST clients.
We are currently trying to get the Json data from JsonStub using AngularJS. We tried to replicate JsonStub's example but had no luck getting this to work with our apikeys.
We just want to show {"message":"hello world!"} within AngularJS from JsonStub's.
Here is our code, please let me know we're doing wrong.
Thank you.
Controller
.controller('warrantyListController', function($scope, $http) {
$http({
url: 'http://jsonstub.com/jobs',
method: 'GET',
dataType: 'json',
data: '',
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'xxxxx-xxxxx-xxxxx-xxxxx',
'JsonStub-Project-Key': 'xxxxx-xxxxx-xxxxx-xxxxx'
}
})
.success(function (data, status, headers, config) {
alert(JSON.stringify(data, null, 4));
});
})
JsonStub
To do with the fact that its a cross domain request. Open up F12 dev tool and have a look.
XMLHttpRequest cannot load http://jsonstub.com/jobs. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://run.plnkr.co' is therefore not allowed access. The response had HTTP status code 500.
Actual Fix
Add the following header
'Access-Control-Allow-Origin': 'http://jsonstub.com'
or, to allow all
'Access-Control-Allow-Origin': '*'
Possible addition to fix, depending on Angular version
There has been a know issue in previous versions of Angular with CORS, but it can be resolved with the following config change:
.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
})