In my Ruby on Rails application I tried to upload an image through the POSTMAN REST client in Base64 format. When I POST the image I am getting a 406 Not Acceptable Response. When I checked my database, the image was there and was successfully saved.
What is the reason for this error, is there anything I need to specify in my header?
My request:
URL --- http://localhost:3000/exercises.json
Header:
Content-Type - application/json
Raw data:
{
"exercise": {
"subbodypart_ids": [
"1",
"2"
],
"name": "Exercise14"
},
"image_file_name": "Pressurebar Above.jpg",
"image":"******base64 Format*******"
}
Your operation did not fail.
Your backend service is saying that the response type it is returning is not provided in the Accept HTTP header in your Client request.
Ref: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
Find out the response (content type) returned by Service.
Provide this (content type) in your request Accept header.
http://en.wikipedia.org/wiki/HTTP_status_code -> 406
406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not
acceptable according to the accept headers sent in the request.
406 happens when the server cannot respond with the accept-header specified in the request.
In your case it seems application/json for the response may not be acceptable to the server.
You mentioned you're using Ruby on Rails as a backend. You didn't post the code for the relevant method, but my guess is that it looks something like this:
def create
post = Post.create params[:post]
respond_to do |format|
format.json { render :json => post }
end
end
Change it to:
def create
post = Post.create params[:post])
render :json => post
end
And it will solve your problem. It worked for me :)
"Sometimes" this can mean that the server had an internal error, and wanted to respond with an error message (ex: 500 with JSON payload) but since the request headers didn't say it accepted JSON, it returns a 406 instead. Go figure. (in this case: spring boot webapp).
In which case, your operation did fail. But the failure message was obscured by another.
You can also receive a 406 response when invalid cookies are stored or referenced in the browser - for example, when running a Rails server in Dev mode locally.
If you happened to run two different projects on the same port, the browser might reference a cookie from a different localhost session.
This has happened to me...tripped me up for a minute. Looking in browser > Developer Mode > Network showed it.
const request = require('request');
const headers = {
'Accept': '*/*',
'User-Agent': 'request',
};
const options = {
url: "https://example.com/users/6",
headers: headers
};
request.get(options, (error, response, body) => {
console.log(response.body);
});
Changing header to Accept: */* resolved my issue and make sure you don't have any other Accept Header
In my case, I added:
Content-Type: application/x-www-form-urlencoded
solved my problem completely.
If you are using 'request.js' you might use the following:
var options = {
url: 'localhost',
method: 'GET',
headers:{
Accept: '*/*'
}
}
request(options, function (error, response, body) {
...
})
In my case for a API in .NET-Core, the api is set to work with XML (by default is set to response with JSON), so I add this annotation in my Controller :
[Produces("application/xml")]
public class MyController : ControllerBase {...}
Thank you for putting me on the path !
It could also be due to a firewall blocking the request. In my case the request payload contained string properties - "like %abc%" and ampersand symbol "&" - which caused the firewall to think it is a security risk (eg. a sql injection attack) and it blocked the request. Note here the request does not actually go to the server but is returned at the firewall level itself.
In my case, there were no application server logs generated so I knew that the request did not actually reach the server and was blocked before that. The logs that helped me were Web application firewall (WAF) logs.
Related
The Angular Server Sent Event this.eventSource.onmessage call fails with an error "EventSource's response has a MIME type ("application/json") that is not "text/event-stream". Aborting the connection." I see in the Chrome Dev Tools (image attached) that there are two Content-Type being returned.
Backend Code:Spring Reactor/REST
#GetMapping(value="/events",produces = "text/event-stream;charset=UTF-8")
public Flux<ConsumerEvent> getProductEvents(){
return kafkaService.getReceiverRecordAllFlux()
.map(record->
new ConsumerEvent(record.topic(),record.value())
);
}
}
Front end:Angular
public startKafkaTopicInfoEventSource(): void {
let url = BASE_URL;
this.eventSource = new EventSource(url);
this.eventSource.onmessage = (event) => {//Error: EventSource's response has a MIME type ("application/json") that is not "text/event-stream". Aborting the connection
this.zone.run(() => {
// some code here
})
}
// other code here
}
The method this.eventSource.onmessage gives an error EventSource's response has a MIME type ("application/json") that is not "text/event-stream". Aborting the connection.
Any help would be great!
I had the same problem using ASP.NET (and nodeJS).
I don't know if this helps but I experienced that, if you use Moesif Origin & CORS Changer (in the standard configuration, I didn't test custom one) some Headers get added or overwritten (the "new" one is chosen) by the plugin (at least Content-Type and X-Content-Type-Options) as we see in your Dev Tool Screenshot.
So Maybe some plugin you installed in Chrome causes this. Try running in a different Browser or without Plugins.
Hope I can help somebody and have a nice day!
I had the same problem, somewhere in your eventSource.onmessage, the code change MIME type value to {'content-type': 'application/json'}, you have to keep it with the value of {'content-type':'text/event-stream'}
I know it is possible to get a cookie in lambda proxy. I can't find any sources on retrieving the cookies except in node.js (but it isn't in the same format). Can anyone point me in the right direction?
Cookie can be set up in the response headers. Return as a response something like this:
{
statusCode: 200,
headers: {'Set-Cookie': 'key=val'},
body: 'Some response'
}
To read cookies you need to check the request header. It's provided in the event from API Gateway. It's either event.headers.Cookie.
I'm trying to hit my server's endpoint with a multipart/form-data request sent from Postman. I'm getting a 400 Bad Request and the cause is:
org.jvnet.mimepull.MIMEParsingException: Missing start boundary.
How can I set the start boundary and how do I know what it should be?
https://github.com/postmanlabs/postman-app-support/issues/191 Following that thread here seems that setting the request header to Content-Type multipart/form-data I'm overriding the value set by Postman.
There is no need to add a content-type header manually. You are
overriding the value set by Postman. Just select form-data in POST
request and send your request to see if it works.
Removing the header allowed me to hit my endpoint.
Overriding POSTMAN header values is the issue as mentioned by Anton above. Here is how your headers and request body should look like for standalone POSTMAN client:
As a work around try this:
spring:
jersey:
application-path: /rest # Path that serves as the base URI for the application. Overrides the value of "#ApplicationPath" if specified.
filter.order: 0 # Jersey filter chain order.
type: servlet # Can be either "servlet" or "filter".
init.*:
type servlet worked fine, where as filter is throwing the Start Boundary error.
even though i have appended my service response with following provided CORS Headers :
resp.setContentType("application/json");
resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Access-Control-Allow-Credentials", "true");
resp.addHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
resp.addHeader("Access-Control-Allow-Headers", "Origin,accept,content-type");
resp.flushBuffer();
i am still getting below error in the console while trying to access some of the POST web methods in the service through my AngularJS frontend.
XMLHttpRequest cannot load http://192.***.*.***:8080/abc/def/search/vehicleManufacturer. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.***.*.***:8085' is therefore not allowed access.
However within the same class, some POST methods without any payloads are responding perfectly. Any suggestions ?
EDIT--------->
Below is my AngularJS client screen code for calling the web method:-
getVehicleModel : function(searchData,$scope){
$http({
method:'POST',
url:'http://192.169.*.***:8085/abc/def/search/vehicleModel',
dataType:'jsonp',
data:searchData
}).
success(function(data){
console.log("vehicle model")
$scope.vehicleModel = data.Response;
});
},
I think the problem here is Preflighted Requests in CORS.
From the Mozilla docs,
Unlike simple requests (discussed above), "preflighted" requests first
send an HTTP request by the OPTIONS method to the resource on the
other domain, in order to determine whether the actual request is safe
to send. Cross-site requests are preflighted like this since they may
have implications to user data. In particular, a request is
preflighted if:
It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than
application/x-www-form-urlencoded,
multipart/form-data
text/plain
e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)
As explained above, even though you're making a simple POST request, the Content-Type in your request is application/json which is different from the 3 types mentioned above, so it's considered as a Preflight request and an OPTIONS request is fired before your actual POST request.
You can solve this by implementing doOptions in your servlet, just add the headers there and it will work :)
The preflight (OPTIONS) is occurring due to the fact that you are sending a cross-origin ajax request AND specifying an Authorization header with this GET request.
Also (this is not causing an issue) I would suggest removing the contentType option. This doesn't make sense in the context of a GET request. A GET request should not have any content. All data should be included in the query string or, possibly, headers.
The Authorization header will not be sent with the OPTIONS. You must acknowledge it server-side, and then the browser will send the underlying GET. Read more about CORS at https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS .
I have a problem with method generating PNG image responses.
#RequestMapping(value = "/thumb/{id}.png", produces = "image/png")
#ResponseBody
public char[] thumb(#PathVariable UUID id)
{
// action logic here
return CatalogController.PLACEHOLDER_THUMB;
}
However I can't access this action - it is executed correctly (I see logic effects in database), but client gets 406 Not Acceptable.
Here is how I simulate the request (same happens in Chrome and Internet Explorer):
$ wget "http://localhost:8080/thumb/13164e6b-fc0f-4c67-a7d3-e2c56224384b.png" -O - --header="Accept: image/png"
--2013-11-18 18:37:30-- http://localhost:8080/thumb/13164e6b-fc0f-4c67-a7d3-e2c56224384b.png
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8080... connected.
HTTP request sent, awaiting response... 406 Not Acceptable
2013-11-18 18:37:30 ERROR 406: Not Acceptable.
Edit
Here is more detailed description displayed in browser:
description The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ().
Ok, thanks for everyone for helping, but the answer is far more trivial - it's simply not possible to use char[] as response content.
Switched to byte[] and everything worked fine!
(probably could be possible to register handler for byte[] but it's not needed for me, so can't confirm that).