I'm trying to get a token from the ArcGIS Online service using a Javascript. However, it's always returning an error which indicates the client_id isn't specified.
Am I doing everything right here?
<script type="text/javascript">
var MyJSONText = '{"client_id":"<<MY_CLIENT_ID>>","client_secret":"<<MY_CLIENT_SECRET>>","grant_type":"client_credentials","expiration":"1440","f":"json"}';
var MyJSON = JSON.parse(MyJSONText);
xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.arcgis.com/sharing/rest/oauth2/token/");
xhr.send(MyJSON);
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
alert(xhr.responseText);
}
}
</script>
Edit - full error is:
{"error":{"code":400,"error":"invalid_request","error_description":"client_id not specified","message":"client_id not specified","details":[]}}
I was able to retrieve an access token using application/x-www-form-urlencoded request:
POST https://www.arcgis.com/sharing/rest/oauth2/token HTTP/1.1
User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded
Host: www.arcgis.com
Content-Length: 126
client_id=<YOUR ID>&client_secret=<YOUR SECRET>&grant_type=client_credentials&expiration=1440&f=json
which means that you might need to specify the Content-Type request header when making the XHR request:
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
and of course properly formatting the body as application/x-www-form-urlencoded instead of JSON. In my tests this endpoint didn't work with JSON payload.
Unfortunately from what it looks, the token endpoint doesn't support setting the Content-Type request header in its CORS policy which means that you might be out of luck in calling it with javascript. Besides their documentation doesn't mention anything about javascript as a supported language.
So basically if you want to make this work you could get the access token on your server side and pass it along to the client.
Access Token Generation Url =>https://www.arcgis.com/sharing/rest/oauth2/token
Headers
enter image description here
For the Case of body in Post man select 'x-www-form-urlencoded'
enter image description here
After that you will get the respective expected result with token
{"access_token":"S-z3mxAqsZBeihx8NgFmNGsZAUGfzKZWCYVV2TiQO422u9XDLTCTZAkpoecyxx_LAc71I_tPkeeOlo2Pzkapv01bBOA03SzMRjRMOm-h3ljTl-pb3XdffoyYjCflE4F8LD377DbpjDWkupkdTaxJpg..","expires_in":7200}
Related
I have the following code utilizing XMLHttpRequest:
const xhr = new XMLHttpRequest();
xhr.open('PUT', url);
xhr.addEventListener('readystatechange', () => {
if (xhr.readyState === 4 && xhr.status === 200) {
const eTag = xhr.getResponseHeader('ETag');
console.log({ eTag, headers: xhr.getAllResponseHeaders() });
}
});
xhr.send(chunk);
When I run this code and look at the response in the Firefox developer tools I see that the response has an ETag header of a long Base64 string:
However, when I look in the console, I see an ETag header that is nowhere near the same:
Object { eTag: "0.07594210872820828", headers: "content-length: 0\r\netag: 0.07594210872820828\r\n" }
Rather than the Base64 string I'm seeing in the devtools, I'm getting a float as a string that doesn't appear to have any relation to the Base64 string. There is only one header that looks anything like ETag:
This is CloudFlare R2 for whatever that's worth. As you can see I have CORS configured so the service responds with Access-Control-Expose-Headers: ETag.
What's going on that the JavaScript code appears to be getting a different value from what is shown in the developer tools?
Turns out it was this extension: https://github.com/ClearURLs/Addon
It has an option that is enabled by default: Filters ETag Headers From Requests. Turning that option off fixed the issue.
My goal
I am doing .aspx file on Microsoft Visual Studio. What I expect is that the system will scan the QR code and then send the JSON data to the server side.
PS. I am using XMLHttpRequest to send the data.
What I Get
First I tried to pass it directly, it does not work so I check its status and readyStats, what it shows is 1(open) and 0(not initialized) (I am expecting 4(done) and 200(ok)) the responseText is null. I then inspected my browser (Google Chrome), the console shows an error "Access to XMLHttpRequest at 'https://website-A.aspx' from origin 'https://localhost:44371' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
What I tried
So I searched for solution on stack overflow, most of them says that I need to put in the header Access-Control-Allow-Origin:* to the server, but the problem is I do not have the control of the server but I do contacted them to change the code to try it out, end up Access-Control-Allow-Origin:* doesn't work so I looked for alternative. I tried to use plugin such as Moesif Origin & CORS Changer but it shows "Access to XMLHttpRequest at 'https://website-A.aspx' from origin 'https://localhost:44371' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.".
Below is my code:
function onScanSuccess(qrCodeMessage) {
...
var url = "https://Website-A.aspx";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open("POST", url);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log(xhr.status);
console.log(xhr.responseText);
}
};
//I hardcoded the data for testing
var data = {
"SOME_ID": "Value",
"SOME_TYPE": "Value",
"SOME_ID": "Value",
"SOME_AMT": "Value",
"SOME_AMT_CURRENCY": "Value",
"SOME_DESC": "Value",
...
};
xhr.send(data);
}
Is there anyway to solve this without changing the server side's code or bypassing the CORS?
I wish to solve this by modify the code in the same .aspx only, is it possible?
If my code ain't going to work, is there any other way to do it?
Any helps will be appreciated.
cors must be allowed on server side. your code looks ok.
sorry, i can't use the comment function yet
I want to made simple post request on Ebay trading api with javascript Ajax. Here is the call format. I got some error on the following request. can anyone tell me the what wrong with the call .
const findbtn = document.querySelector(".find-item-btn");
findbtn.addEventListener("click", getData);
function getData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
console.log(this.responseText);
};
const xml =
'<?xml version="1.0" encoding="utf-8"?>' +
'<GetItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">' +
"<ErrorLanguage>en_US</ErrorLanguage>" +
"<WarningLevel>High</WarningLevel>" +
"<ItemID>232789363104</ItemID>" +
"</GetItemRequest>";
xhttp.open("POST", "https://api.ebay.com/ws/api.dll", true);
xhttp.setRequestHeader("X-EBAY-API-COMPATIBILITY-LEVEL", "967");
xhttp.setRequestHeader("X-EBAY-API-DEV-NAME","6cfe5ebb-73c4-465b-ad24-c4f0aea8de0");
xhttp.setRequestHeader("X-EBAY-API-APP-NAME","RegnantC-SaveWix-PRD-3ef66784f-24730a7");
xhttp.setRequestHeader("X-EBAY-API-CERT-NAME","PRD-ef66784f85c1-6c65-4919-bc83-24c6");
xhttp.setRequestHeader("X-EBAY-API-CALL-NAME", "GetItem");
xhttp.setRequestHeader("X-EBAY-API-SITEID", "0");
xhttp.setRequestHeader("Content-Type", "text/xml");
xhttp.setRequestHeader("Access-Control-Allow-Origin", "*");
xhttp.setRequestHeader("Access-Control-Allow-Headers","X-Requested-With, Origin, Content-Type, X-Auth-Token");
xhttp.setRequestHeader("Access-Control-Allow-Methods","GET, PUT, POST, DELETE");
xhttp.setRequestHeader("X-EBAY-API-IAF-TOKEN","v^1.1#i^1#f^0#r^0#p^3#I^3#t^H4sIAAAAAAAAAOVYeWwUVRjv9lJEaIigTUWzTiEeOLtz7e7sh"
);
xhttp.send(xml);
}
and got the following error
1 Access to XMLHttpRequest at 'https://api.ebay.com/ws/api.dll' from origin 'localhost/app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
2 POST https://api.ebay.com/ws/api.dll net::ERR_FAILED
Please help me. is the right format for the ajax request
Actually it's causing the CORS error. You can read about it details from here https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
And if you want to overcome this issue you can enable CORS from server. I mean send the request through your server.
Or you can also use CORS anywhere header.
const corsHeader = "https://cors-anywhere.herokuapp.com/";
then use this corsHeader appending with your url like this,
xhttp.open("POST", corsHeader+"https://api.ebay.com/ws/api.dll", true);
It'll send the request and currently it's showing error: IAF token supplied is invalid. If you provide proper IAF token then it'll provide you the data.
I'm very new to programming in general so this will not be a technical answer in the least, but.... I did get this to eliminate the CORS error.
const corsHeader = "https://cors-anywhere.herokuapp.com/";
xhttp.open("POST", "https://api.ebay.com/identity/v1/oauth2/token", true);
xhttp.open("POST", corsHeader, true);
I had to go here first and enable temporary access though.
https://cors-anywhere.herokuapp.com/corsdemo
Now when I run this the console is saying:
"This API enables cross-origin requests to anywhere."
If I can figure out how to get any farther I will update this thread.
The exact error that I am struggling with is "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.".
I am trying to fetch JSON data using JavaScript from https://api.kraken.com/0/public/OHLC?pair=ETHEUR. I created a XMLHttpRequest object to do this, and specified GET as the type of request. This is supposedly a simple request, however the error says that a preflight request was sent. What is the reason for this behavior? That being said, to fix this error I tried to set a request header in which I specified '*' as the value for the Access-Control-Allow-Origin, yet I still get an error. I have looked through responses to similar questions as mine, but haven't been able to figure out how to solve the problem I am dealing with. This is probably due to still being very new to JavaScript. Either way, below is the code that I have written:
var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR'
var request = new XMLHttpRequest();
request.open('GET',requestURL,true);
request.responseType = 'json';
request.onload = function(){
var data = request.response;
console.log(data);
}
request.setRequestHeader('Access-Control-Allow-Origin','*');
request.send();
In cases like this where the server you’re trying to make a cross-origin request to doesn’t send the Access-Control-Allow-Origin response header, your only option, if you want to make a request to that server from frontend JavaScript code running in a browser, is to use a CORS proxy. Otherwise, your browser won’t allow your frontend JavaScript code to access the response.
So, you can make your request succeed if you change your code to have something like this:
var proxyURL = 'https://cors-anywhere.herokuapp.com';
var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR';
var request = new XMLHttpRequest();
request.open('GET', proxyURL + '/' + requestURL, true);
That sends the request through https://cors-anywhere.herokuapp.com, which forwards the request to https://api.kraken.com/0/public/OHLC?pair=ETHEUR and then receives the response. The https://cors-anywhere.herokuapp.com backend adds the Access-Control-Allow-Origin header to the response and passes that back to your requesting frontend code.
The browser will then allow your frontend code to access the response because that response with the Access-Control-Allow-Origin response header is what the browser sees.
You can also easily set up your own CORS proxy using https://github.com/Rob--W/cors-anywhere/
Note also that request.setRequestHeader('Access-Control-Allow-Origin','*') needs to be removed from the frontend code you are making the request with (as mentioned in comments above).
That’s because Access-Control-Allow-Origin is strictly a response header for servers to send in responses; sending it from the client side in a request will have no effect other than to trigger your browser to do an unnecessary CORS preflight OPTIONS request that will fail.
For details about what browsers do when you send cross-origin requests from frontend JavaScript code using XHR or the Fetch API or AJAX methods from JavaScript libraries—and details about what response headers must be received in order for browsers to allow frontend code to access the responses—see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.
var proxyURL = 'https://cors-anywhere.herokuapp.com';
var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR';
var request = new XMLHttpRequest();
request.open('GET', proxyURL + '/' + requestURL, true);
request.responseType = 'json';
request.onload = function() {
var data = request.response;
document.querySelector('pre').textContent = JSON.stringify(data, null, 2);
}
request.send();
<pre></pre>
I have a form in a HTML page which does the following:
form method="POST" id="myForm" onsubmit="callSlates();">
Javascript function is as follows:
function callSlates(){
var form=document.getElementById('myForm');
form.action = "https://dev1-apiservicesweb.dev.jabs.com:8111/api/v1/systems/slates";
// collect the form data while iterating over the inputs
var data = {};
for (var i = 0, ii = form.length; i < ii; ++i) {
var input = form[i];
if (input.name == "ID1") {
data[input.name] = input.value;
}
if (input.name == "SDCode") {
data[input.name] = input.value;
}
}
var xhr = new XMLHttpRequest();
xhr.open('POST', form.action);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
xhr.send(JSON.stringify(data));
}
//return false;
}
POST calls are happening but when I check the Request Header, it shows that the application/x-www-form-urlencoded and am ending with error 504-Gateway Timeout Error
The endpoint I am calling expects json header and JSON data. I believe I am doing that but when I used Chrome developer tools, I don't see that. Has it got something to do with the way am making the call?
Edit: When I tried hitting that URL with Postman, with header and body as JSON, am getting 200 response (as expected).
UPDATE: I understood that the form was getting submitted rather than the Ajax call and thus took Barmar advice and put return false; in form onsubmit. Now am not getting 504 anymore and getting 405 instead.
Following is the request header am seeing currently:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:dev1-apiservicesweb.dev.jabs.com:8111
Origin:http://localhost:3000
And in general information, it says:
Request Method:OPTIONS
Status Code:405
As per le_m, could this be a CORS issue?
Since your request works from your local host via postman but not from within the browser, the culprit is probably the Same Origin Policy:
Your browser attempts to send a Cross Origin Request (CORS). There are two types of CORS requests:
Preflighted requests: The browser first asks the server about supported HTTP methods by sending an HTTP OPTIONS request followed by the actual HTTP request upon approval.
Simple requests: The browser directly sends the actual HTTP request.
Now, which of the above does your browser choose? MDN states that simple requests will be send if the Content-Type is one of the following:
application/x-www-form-urlencoded
multipart/form-data
text/plain
However, Content-Type: application/json is not allowed for simple requests. Thus, you currently send preflighted CORS requests. You can verify that by opening the developer console e.g. in Firefox: You will notice that your code first sends an OPTIONS request.
Now, this OPTIONS request receives a 405 Method not allowed error. This indicates that the server doesn't support preflighted CORS requests. You either need to change the server configuration OR change the Content-Type to one of the compatible ones listed above. If your server can't accept one of those content types, then you are probably out of luck.
See also this answer given by #ArslanTariq in reply to a similar issue.
You're not preventing the normal form submission. Change your form to:
<form method="POST" id="myForm" onsubmit="callSlates();return false;">
return false; prevents the default submit action.
There's also no need to set form.action in your function, since you don't want to submit the form normally.