I'm trying to write a submit form that sends a JSON object to an application on another server but I keep getting a 405 Method Not Allowed error in the console.
The app is set up to accept POST and that's what I'm sending so I'm lost at where the error is. There is also a warning in the console Loading failed for the <script> with source "Request URL"
Is this a problem with the way the application is reading the JSON or the format the JSON is being sent in?
From the app server
Failed to execute: javax.ws.rs.NotSupportedException: RESTEASY003065: Cannot consume content type
Code
json = JSON.parse(string);
$.ajax({
type: 'POST',
dataType: "jsonp",
contentType: "application/json",
url: "http://test:8080/request/committee",
data: json,
cache: false,
success: function (response) {
$("#successModal").modal('show');
},
failure: function (response) {
$("#failureModal").modal('show');
},
error: function (response) {
$("#failureModal").modal('show');
}
});
e.preventDefault();//prevents the form from being submitted by default
Request Headers
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Host: test:8080
Referer: http://www.form.com/servlet/rsvp.jsp?location=110%20Road%20Bolton%20Landing,%20NY&purpose=%20TPAS%20Teleconference%20(RSVP%20here%20to%20attend%20in-person)&visitDate=2018-03-15&visitStartTime=6:00%20AM&visitEndDate=7:00%20AM&committee=all
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Response Headers
HTTP/1.1 405 Method Not Allowed
Allow: POST, OPTIONS
Connection: keep-alive
Content-Length: 0
Date: Mon, 16 Apr 2018 15:38:24 GMT
Edit: corrected contentType. Same error occurs
From your exception details , it seems to be
Failed to execute: javax.ws.rs.NotSupportedException: RESTEASY003065: Cannot consume content type
either you are passing invalid content type or not passing at all , I see your content type is application/jsonp.
just give a try with application/javascript.
This error happened to me once. My java method wanted xml not json. this annotation (in java) fixed it for me.
#Consumes(MediaType.APPLICATION_JSON)
I hope this helps!
I am using the below Ajax call to connect with Spring security from crossdomain (PhoneGap). The response I got is 200 OK - it has the expected response in JSON format. But the error event is getting fired due to CORS. On the Spring side, I have added a CORS filter to allow any type of URL (Access-Control-Allow-Origin = ' * ').
$.ajax({
type:'POST',
url: CONTEXTPATH + '/j_spring_security_check',
data: formData,
dataType: 'text json',
cache: false,
crossdomain: false,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With' : 'XMLHttpRequest',
},
success: function(data) {
},
error: function(data) {
}
});
The response in the browser console is:
POST XHR http://192.168.0.20:8080/startupbay/j_spring_security_check [HTTP/1.1 200 OK 260ms] Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://192.168.0.20:8080/startupbay/j_spring_security_check. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
The request and response headers are:
RESPONSE HEADER:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, x-requested-with, Origin, Accept
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD
Access-Control-Allow-Origin:*
Access-Control-Max-Age:86400
Access-Control-Request-Headers:x-requested-with
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date: Thu, 23 Feb 2017 06:14:39 GMT
Expires:0
Pragma:no-cache
Server:Apache-Coyote/1.1
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
REQUEST HEADER:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.5
Access-Control-Request-Headers:x-requested-with
Access-Control-Request-Method:POST
Connection:keep-alive
Host:192.168.0.20:8080
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
origin:http://192.168.0.20:3000
In the Error section, I looked for the error mentioned in 'xhr'. The statusText:error, responseText:'', status:0.
Please help me in resolving this issue.
When I set the crossdomain:true, that time in the browser console I can see only the OPTIONS request, but not followed by the POST request.
Just to add, this issue is appearing only for the '/j_spring_security_check' URL. For another URL, the same type setup is working fine.
Okay, I've looked all over for this. Basically we're using $http request that ARE cross domain requests. Our server allows the domain and when a request returns 200, everything is OK. However, anytime our server returns an error, 500, 401, whatever, Angular thinks it's a CORS issue.
I debugged the response with Fiddler to verify my server IS returning a 500, yet Angular chokes on it.
Here's the request:
var params = {
url: "fakehost/example",
method: 'GET',
headers: {
"Authorization": "Basic encodedAuthExample"
}
};
$http(params).then(
function (response) { // success
},
function (error) { // error
// error.status is always 0, never includes data error msg
});
Then in the console, I will see this:
XMLHttpRequest cannot load fakehost/example. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'mylocalhost:5750' is therefore not allowed access.
Yet, in fiddler, the true response is:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 26 Aug 2014 12:18:17 GMT
Content-Length: 5683
{"errorId":null,"errorMessage":"Index was outside the bounds of the array.","errorDescription":"Stack trace here"}
I'm on AngularJS v1.2.16
I think I found an answer, looks like you will have to inject in your asp.net pipeline the correct CORS headers, as mentioned here.
I am a novice to angular.js, and I am trying to add some headers to a request:
var config = {headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose'
}
};
$http.get('https://www.example.com/ApplicationData.svc/Malls(1)/Retailers', config).success(successCallback).error(errorCallback);
I've looked at all the documentation, and this seems to me like it should be correct.
When I use a local file for the URL in the $http.get, I see the following HTTP request on the network tab in Chrome:
GET /app/data/offers.json HTTP/1.1
Host: www.example.com
Connection: keep-alive
Cache-Control: max-age=0
If-None-Match: "0f0abc9026855b5938797878a03e6889"
Authorization: Basic Y2hhZHN0b25lbWFuOkNoYW5nZV9tZQ==
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
If-Modified-Since: Sun, 24 Mar 2013 15:58:55 GMT
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
X-Testing: Testing
Referer: http://www.example.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
As you can see, both of the headers were added correctly. But when I change the URL to the one shown in the $http.get above (except using the real address, not example.com), then I get:
OPTIONS /ApplicationData.svc/Malls(1) HTTP/1.1
Host: www.datahost.net
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://mpon.site44.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Access-Control-Request-Headers: accept, origin, x-requested-with, authorization, x-testing
Accept: */*
Referer: http://mpon.site44.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
The only difference in code between these two is one is for the first the URL is a local file, and for the second the URL is a remote server. If you look at the second Request header, there is no Authentication header, and the Accept appears to be using a default instead of the one specified. Also, the first line now says OPTIONS instead of GET (although Access-Control-Request-Method is GET).
Any idea what is wrong with the above code, or how to get the additional headers included using when not using a local file as a data source?
I took what you had, and added another X-Testing header
var config = {headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose',
"X-Testing" : "testing"
}
};
$http.get("/test", config);
And in the Chrome network tab, I see them being sent.
GET /test HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Authorization: Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==
X-Testing: testing
Referer: http://localhost:3000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Are you not seeing them from the browser, or on the server? Try the browser tooling or a debug proxy and see what is being sent out.
Basic authentication using HTTP POST method:
$http({
method: 'POST',
url: '/API/authenticate',
data: 'username=' + username + '&password=' + password + '&email=' + email,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Login-Ajax-call": 'true'
}
}).then(function(response) {
if (response.data == 'ok') {
// success
} else {
// failed
}
});
...and GET method call with header:
$http({
method: 'GET',
url: '/books',
headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json',
"X-Login-Ajax-call": 'true'
}
}).then(function(response) {
if (response.data == 'ok') {
// success
} else {
// failed
}
});
If you want to add your custom headers to ALL requests, you can change the defaults on $httpProvider to always add this header…
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common = {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose'
};
}]);
my suggestion will be add a function call settings like this
inside the function check the header which is appropriate for it. I am sure it will definitely work. it is perfectly working for me.
function getSettings(requestData) {
return {
url: requestData.url,
dataType: requestData.dataType || "json",
data: requestData.data || {},
headers: requestData.headers || {
"accept": "application/json; charset=utf-8",
'Authorization': 'Bearer ' + requestData.token
},
async: requestData.async || "false",
cache: requestData.cache || "false",
success: requestData.success || {},
error: requestData.error || {},
complete: requestData.complete || {},
fail: requestData.fail || {}
};
}
then call your data like this
var requestData = {
url: 'API end point',
data: Your Request Data,
token: Your Token
};
var settings = getSettings(requestData);
settings.method = "POST"; //("Your request type")
return $http(settings);
What you see for OPTIONS request is fine. Authorisation headers are not exposed in it.
But in order for basic auth to work you need to add: withCredentials = true; to your var config.
From the AngularJS $http documentation:
withCredentials - {boolean} - whether to to set the withCredentials
flag on the XHR object. See requests with credentials for more
information.
And what's the answer from the server? It should reply a 204 and then really send the GET you are requesting.
In the OPTIONS the client is checking if the server allows CORS requests. If it gives you something different than a 204 then you should configure your server to send the correct Allow-Origin headers.
The way you are adding headers is the right way to do it.
Chrome is preflighting the request to look for CORS headers. If the request is acceptable, it will then send the real request. If you're doing this cross-domain, you will simply have to deal with it or else find a way to make the request non-cross-domain. This is by design.
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, or 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)
Ref: AJAX in Chrome sending OPTIONS instead of GET/POST/PUT/DELETE?
You are just adding a header which server does not allow.
eg - your server is set up CORS to allow these headers only (accept,cache-control,pragma,content-type,origin)
and in your http request you are adding like this
headers: {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json',
'x-testing': 'testingValue'
}
then the Server will reject this request since (Authorization and x-testing) are not allowed.
This is server side configuration.
And there is nothing to do with HTTP Options, it is just a preflight to server which is from different domain to check if server will allow actual call or not.
For me the following explanatory snippet worked. Perhaps you shouldn't use ' for header name?
{
headers: {
Authorization: "Basic " + getAuthDigest(),
Accept: "text/plain"
}
}
I'm using $http.ajax(), though I wouldn't expect that to be a game changer.
I'm trying to save a Backbone model in couchdb so I've overridden the save method with a ajax requet to couchdb:
$.ajax({
type: 'PUT',
url: 'http://127.0.0.1:5984/movies/' + this.get('id'),
contentType: 'application/json',
data: JSON.stringify(this.toJSON()),
success: function() {
console.log('asdf');
},
failure: function() {
console.log('test');
}
});
The request is sent but when I look at the couchdb log jQuery seems to send a OPTIONS HTTP method instead of PUT:
[info] [<0.1601.0>] 127.0.0.1 - -
'OPTIONS' /movies/862 405
and couchdb sends a 405 HTTP Response code (method not allowed). Any Ideas?
Edit
Here are the headers sent to CouchDB:
OPTIONS /movies/862 HTTP/1.1
Host: 127.0.0.1:5984
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://localhost:8888
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type
There's a backbone connector for couch-db.. https://github.com/janmonschke/backbone-couchdb
PUT isn't supported by all browsers. Also, the property for your data is "data", not "body".