I am trying to call an API that accepts OPTIONS method on server, it runs on postman and returns json object but following code is not working on js
I have read that OPTIONS call is a preflight call for CORS calls, so this API is https and on another server. But even then there is no response and it returns 405 method not found
$.ajax({
url: url,
dataType: "jsonp",
method :"OPTIONS",
crossDomain: true,
contentType: 'application/json',
headers: {
"Content-type": "application/json",
"Cache-Control": "no-cache",
"Accept": "application/json,long_format",
"Access-Control-Allow-Origin": "*"
},
success: function (data) {
console.log("success" + data);
},
error: function (data) {
console.log("fail" + data);
}
}).fail(function(data) {
console.log("failed" + data);
});
Extra info :
The API is cross domain and on ssl so to cover cross domain request I had to user dataType: "jsonp"
UPDATED :
This is impossible scenario so I have to get update on server end...
Explanation:
There is some problem with
OPTIONS method that is behind cross domain as well
a/c to some research i have done on internet, CORS request can be accessed with :
dataType: "jsonp",
but with -> dataType: "jsonp"
you can only call GET methods
so we are stuck here that allows that either we call cross domain https request or we can call OPTIONS method,
usually OPTIONS method is a preflight method done automatically by browser
NOW please stop down voting my question
dataType: "jsonp",
Take this out. JSONP requests are always GET requests. This is your main problem.
crossDomain: true,
Take this out. It does nothing unless you are making a same origin request that gets redirected to be a cross origin request.
contentType: 'application/json',
Take this out. You are making an OPTIONS request. There is no request body to describe the content-type of.
"Content-type": "application/json",
Take this out. For the same reason.
"Access-Control-Allow-Origin": "*"
Take this out. It is a response header and has no place on the request.
Related
Here when I trying to print response in browser console. It shows this error
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://script.google.com/macros/s/AKfycbwmqG55tt2d2FcT_WQ3WjCSKmtyFpkOcdprSITn45-4UgVJnzp9/exec?url=http://35.230.52.177:8095/OneSoftTracking/rest/tracking/consignment/AE101632?hostname=aastha-enterprises.com&callback=jQuery1124008693115102408444_1561964934754&_=1561964934755 with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.`
While when I get data in Postman like:
This warning or error showing :
This is my code :
var settings = {
async: true,
crossDomain: true,
crossOrigin: true,
url: "http://35.230.52.177:8095/OneSoftTracking/rest/tracking/consignment/AE101632?hostname=aastha-enterprises.com",
method: "GET",
"headers": {
"Content-Type":"application/json",
"Access-Control-Allow-Origin":"*",
'Access-Control-Allow-Methods':'GET',
'Access-Control-Allow-Credentials' : true,
"Accept": "*/*",
"Cache-Control": "no-cache",
"Postman-Token": "bea2b074-eefc-473e-84d7-b680a07ed7df,dafa4f5c-94af-4efe-967f-75a9fe185a1e",
},
success: function(data) {
console.log("+++++SuCCESS");
console.log(data);
},
error: function(error){
console.log("NOT SUCCEED");
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
You haven't shown us your real code.
The error message clearly shows a callback in the query string which isn't in your URL and shouldn't be added because you haven't said dataType: 'jsonp' in the jQuery ajax configuration.
Your real code is configured to use JSONP.
A JSONP response is a JavaScript program (specifically one which calls a single function with a set of arguments). The response you are getting from the server is an HTML document (the content type is text/html and not application/javascript).
The CORB error is the browser telling you that the response is HTML and not JSONP so it is refusing to try to execute it.
The Postman screenshot shows that you are expecting a JSON (still not JSONP) response (but you aren't getting that either).
You need to either:
Change the server to respond with JSONP
Change the request to ask for the correct data (and possibly also change the server to grant you permission to read it using CORS)
Further reading:
What is JSONP, and why was it created?
XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header
Notes about your code:
async: true,
This is the default, get rid of it
crossDomain: true,
This is the default for cross origin requests, get rid of it.
crossOrigin: true,
This is the default for cross origin requests, get rid of it.
method: "GET",
This is the default, get rid of it
"Content-Type": "application/json",
You are making a GET request. There is no request body to describe the type of. This is nonsense. Get rid of it.
"Access-Control-Allow-Origin": "*",
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Credentials': true,
These are response headers, not request headers. Putting them on the request is nonsense. Get rid of them.
"Accept": "*/*",
The default is almost certainly going to be fine. You probably don't need to override it.
"Cache-Control": "no-cache",
The main config option "cache" is probably a better choice than explicitly setting the header.
"Postman-Token": "bea2b074-eefc-473e-84d7-b680a07ed7df,dafa4f5c-94af-4efe-967f-75a9fe185a1e",
The odds of your server caring about this are remote. You can probably get rid of this.
I'm trying to use API to get information about a specific user based on user ID. I need to use basic auth and pass some headers with my call.
I'm getting this:
Cross-Origin Read Blocking (CORB) blocked cross-origin response "rest/user/getProfile?callback=jQuery224033348109431646855_1548684613983&userId=24068..." with MIME type text/plain.
My code:
$.ajax
({
type: 'GET',
crossDomain: true,
async: false,
url: 'example_URL_/api/user/getProfile',
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
beforeSend: function (xhr) { xhr.setRequestHeader("Authorization", "Basic ZHVubmVzYXBpskjoi43u5409543o9tI654kjhugjy"); },
dataType: 'jsonp',
data: { "Id": "1234" },
success: function (data) {
console.log(data);
},
error: function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
}
});
is there anything I'm missing?
You said:
dataType: 'jsonp',
… so jQuery makes a JSONP request (i.e. inserts a <script> element).
The browser makes a request to the URL and the server said:
Content-Type: text/plain
Since a plain text document is not a JavaScript program, the browser refused to execute it and threw a CORB error instead.
A JSONP response must be application/javascript, not text/plain.
You need to either:
Not make a request for JSONP
Change the server to respond with JSONP
Aside: Since you are using JSONP, the type, crossDomain, async, headers, and xhr.setRequestHeader properties have no effect.
Since you said you needed to set basic auth, that rules out option two. You can't use JSONP for this.
In your API configure CORS to accept all domains, or enter the domain that you're using to send the request from.
If your API is created by PHP here is an example:
<?php
header("Access-Control-Allow-Origin: *");
Or if you are using a third party API, try to see the documentation. I'm sure there will be a part talking about CORS.
I'm having troubles with an AJAX request. I was getting the below error:
Error: Access is denied
I tried this jQuery AJAX request:
$.support.cors = true;
$.ajax({
url: 'http://testwebsite.com/test',
type: "GET",
dataType: 'json',
contentType: 'application/json',
crossDomain: true,
headers: {
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Origin': 'http://testwebsite/test',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Credentials': 'true'
},
xhrFields: {
withCredentials: true
},
success: function(data) {
alert("Data from Server" + JSON.stringify(data));
},
error: function(jqXHR, textStatus, errorThrown) {
alert("You can not send Cross Domain AJAX requests: " + errorThrown);
}
});
Can anyone kindly let me know what I am missing. Thanks in advance.
As rory-mccrossan mentioned in a comment, CORS protection is designed so that a website cannot directly access the content of another website (in a browser) unless the website being accessed agrees to it.
It would completely ruin the point of CORS if a site just has to send some headers in order to circumvent the defence
Instead, you will need to use a CORS proxy. It's a server that when given a request like yourCORSproxy.example.com/http://testwebsite/test would load the page and return it, but with CORS allowed (like a normal proxy but with CORS enabled).
One of these CORS proxies is https://crossorigin.me, but at the time of writing this it is down. It might be more stable if you simply create your own proxy.
tl;dr: testsite.test should be sending the headers on its response. You should not be sending the headers on your request.
Is it possible to make xhr request between domains www.site.mySiteName.com and api.mySiteName.com using JavaScript?
I need to get data from my API in real-time but I don't know how to do it.
Making it possible (Opening your API to your webpage):
You can do ajax requests between domains, however, the host has to allow your origin.
You need to append the header to the response (this needs to be done on the API):
Access-Control-Allow-Origin: *
Or something like:
Access-Control-Allow-Origin: site.mySiteName.com
The API will technically respond to any origin unless you specify otherwise regardless of the header; however, the browser will say the request failed if your origin is now allowed.
Additionally, you should be aware that depending on the request your API will have to support preflight "OPTIONS" requests
See:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
How does Access-Control-Allow-Origin header work?
To actually make the request in javascript:
You can use jQueries "ajax" to make the request: http://api.jquery.com/jquery.ajax/
Simple get request:
$.ajax({
method: "get",
url: "test.html",
}).done(function(data) {
console.log('got data:' + data);
});
Simple post request:
$.ajax({
method: "post",
url: "test.html",
data: {somekey: 'somevalue'}
}).done(function(data) {
console.log('got data:' + data);
});
Format response as JSON:
$.ajax({
method: "get",
url: "test.html",
dataType: "json"
}).done(function(data) {
console.log('got data:' + data);
});
Note(edit): You could do this in native javascript; on the other hand, using jQuery or AngularJS(a full application framework..) is simpler and adds other useful tools.
Currently I am using angularJS and CoffeeScript to try to send a post request, and my sample code is:
login: (user, callback)=>
baseUrl = 'http://localhost:3000/api/v1/sessions'
#$http({
method: 'POST',
url: baseUrl,
data: user
}).success (result)->
callback(result)
But when I call it, it just send 'OPTIONS' request instead of POST request.
And the request detail is:
If I add header to this method,
login: (user, callback)=>
baseUrl = 'http://localhost:3000/api/v1/sessions'
#$http({
method: 'POST',
url: baseUrl,
data: user,
headers:
'Content-Type': 'application/json'
}).success (result)->
callback(result)
It still doesn't works, but if I change headers to 'Content-Type': 'application/x-www-form-urlencoded', then it can send post requests.
But the request Content-type is not not I want.
I also try to modify the request data to JSON by: data: JSON.stringify(user), but still not working.
UPDATES
Guys, I did another spike on this issue. Which is I am jquery to send the request and it works fine, but I found an wired thing that is they have different request data.
Jquery
$.ajax({
type: "POST",
url: "http://localhost:3000/api/v1/sessions",
data: {
"user":{
"email":"wahxxx#gmail.com",
"password":"123456"
}
},
success: function(){
}
Screenshot for Jquery
Angular
login: (user, callback)=>
baseUrl = 'http://localhost:3000/api/v1/sessions'
#$http({
method: 'POST',
url: baseUrl,
data: {
"user":{
"email":"wahxxx#gmail.com",
"password":"123456"
}
},
headers:
'Content-Type': 'application/x-www-form-urlencoded'
}).success (result)->
callback(result)
Now it can send request,but I just got 401 when trying to do request.
Screenshot for Angular
So I think the issue may due to the format of the angular request data.
You are hitting CORS restrictions and same origin policy.
Easiest solution is to deploy web frontend and the api together as one app. If ports are different even on the same machine then one needs to deal with same origin policy.
Options is a preflight query. Make your backend accept it and it should be fine.
More reading:
http://www.html5rocks.com/en/tutorials/cors/