I am trying to make a GET request to AWS S3 using pure Javascript. This is because I am unfortunately no longer able to use the SDK for all of my requests. I have been attempting to follow the documentation provided by Amazon, however I have made very little progress. So far, I have only been able to generate my signature key. I would be enthused if someone could post an example of pure Javascript that makes a simple call to retrieve an object or even lists all of the objects with a specific prefix. I am, to be perfectly honest, completely lost reading their documentation. It seems like it is only useful for people who are intimately familiar with making these calls. #1 and #2 on this image here are what I'm struggling with. I think I sort of understand what they are wanting but I don't know how to fully translate it into an actual request. Unfortunately the code examples on their docs are very few and far between - and a lot of them are just pseudocode/small fractions of the whole thing
edit: Hello is anyone even reading this
edit2: Here's some stuff that isn't working that I'm trying to figure out how to do
var signingKey = getSigningKey(dateStamp, secretKey, regionName, serviceName);
var time = new Date();
//fullURL is something like https://s3.amazon.aws.com/{bucketName}/{imageName}
time = time.toISOString();
time = time.replace(/:/g, '').replace(/-/g,'');
time = time.substring(0,time.indexOf('.'))+"Z";
var request = new XMLHttpRequest();
var canonString = "GET\n"+
encodeURI(fullURL)+"\n"+
encodeURI("Key=asd.jpeg")+"\n"+
"host:s3.amazonaws.com\n"+
"x-amz-content-sha256:"+CryptoJS.SHA256("").toString()+"\n"+
"host;x-amz-content-sha256\n"+
CryptoJS.SHA256("").toString();
var stringToSign = "AWS4-HMAC-SHA256\n"+
time+"\n"+
"20181002/us-east-1/s3/aws4_request\n"+
CryptoJS.SHA256(canonString).toString();
var authString = CryptoJS.HmacSHA256(signingKey, stringToSign).toString();
var queryString = "GET https://s3.amazonaws.com/?Action=GetObject&Version=2010-05-08 HTTP/1.1\n"+
"Authorization: AWS4-HMAC-SHA256 Credential="+accessKey+"/20181002/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature="+authString+"\n"+
"host: s3.amazonaws.com\n"+
"x-amz-date: "+time+"\n";
request.open("GET", "https://s3.amazonaws.com/?Action=GetObject&Version=2010-05-08", false);
request.setRequestHeader("Authorization", "AWS4-HMAC-SHA256 Credential="+accessKey+"/20181002/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature="+authString);
request.setRequestHeader("host", "s3.amazonaws.com");
request.setRequestHeader("x-amz-date", time);
request.send();
edit3: Here are a bunch of errors I get, presumably because I have no idea what I'm doing.
index.js:61 Refused to set unsafe header "host"
index.js:63 OPTIONS https://s3.amazonaws.com/?Action=GetObject&Version=2010-05-08 403 (Forbidden)
index.js:63 Failed to load https://s3.amazonaws.com/?Action=GetObject&Version=2010-05-08: 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.
index.js:63 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://s3.amazonaws.com/?Action=GetObject&Version=2010-05-08'.
You might want to use the SDK, combined with the browser debugger to figure out how the SDK formats the request. In the Chrome debugger Network tab, you can copy the request as a javascript fetch. This will show all the headers you need to set. You can then use this as a basis for your non-SDK code.
Related
I am trying to get the results from wikidata API using a POST XMLHttpRequest to get the results of the query. But only few of the requests pass and some return CORS issue error which is pretty confusing.
My request looks like this, I have set the origin parameter in the url itself as I understood from wikidata documentation. I have also tried setting the origin in the headers which also didn't work.
setTimeout(function () {
var xhr = new XMLHttpRequest();
xhr.open(
"POST",
"https://query.wikidata.org/sparql?origin=*&format=json&query=" +
encodeURIComponent(
queryService(settingsService()).getPropObject(
vm.selected.uri,
prop
)
),
true
);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
let data = JSON.parse(xhr.response);
setObjectInnerHtml(label, data, prop);
}
running -= 1;
};
xhr.send();
}, 300);
But it returns an error at the xhr.send() as shown below:
Access to XMLHttpRequest at 'https://query.wikidata.org/sparql?origin=*&format=json&query=PREFIX%20rdf%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0ASELECT%20DISTINCT%20%3Furi%20%3FuriLabel%20WHERE%20%7B%0A%20%20%3Chttp%3A%2F%2Fwww.wikidata.org%2Fentity%2FQ183%3E%20%3Chttp%3A%2F%2Fwww.wikidata.org%2Fprop%2Fdirect%2FP1889%3E%20%3Furi%20.%0A%20%20OPTIONAL%20%7B%20%3Furi%20rdfs%3Alabel%20%3FuriLabel%20.%20FILTER%20(lang(%3FuriLabel)%20%3D%20%22en%22)%7D%0A%7D' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
What could be going wrong here?
Update
This is the series of requests from the same method, of which it can be seen that some requests pass through and some don't. The error that throws up is the CORS issue.
Okay, I have actually seen this happen to me (not with wikipedia) but with other API servers including some of my own.
After much head banging and trying to exclude other factors (I tried running the code on localhost and on multiple computers), this is what I found out.
The issue was with my ISP. my local ISP had an unreliable DNS server, and the connection would stop and start working, sometimes repeatedly every few seconds. Sometimes, within a second, there were any number of fast connections and disconnections. Every time this happened, the console would keep throwing a CORS error, even though it has nothing to do with CORS itself.
Also, when I deployed this app from localhost to the cloud, I never had any issues. Obviously, the cloud server has zero internet connectivity issues.
In summary, if you are intermittently getting a CORS error (as you have described), I would first start by ensuring that your internet connectivity is reliable.
And, deploy the code to an online cloud server and see if the issue replicates.
Please note : I am assuming that the calls you have mentioned in the screenshot are identical in every possible way. In my case, the issues were happening on identical calls with identical payload data.
This question already has answers here:
XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header
(11 answers)
Closed 4 years ago.
Hi Maybe you can help enlighten me :)
Im trying to make a simple Quote Generator app in pure Javascript (no jQuery), and Im trying to load the following api
https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en
but I keep getting the following error, whether on local host or if I upload it to a host:
Failed to load
https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://127.0.0.1:50969' is therefore not allowed
access.
The code Im using is the below:
// JavaScript Document
var xhr = new XMLHttpRequest();
xhr.open('GET',"https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en",true);
xhr.responseType = 'text';
xhr.send();
xhr.onload = function() {
if(xhr.status === 200) {
var myStuff = JSON.parse(xhr.responseText);
console.log(myStuff);
}
}
If I use an API url with a .json at the end such as:
http://api.wunderground.com/api/3a9c68e56dd0e1fb/conditions/q/90210.json
it works fine, but if I use anything without the .json it gives me that error.
Ive searched all day and cant find a solution and I really don't want to use jQuery for this.
It's about CORS
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
this should help - actually there is no way you could do it from website. your request will be blocked by your browser. what you can probably do is to write backend proxy that will do it.
quick and easy answer - You are requesting a resource that is only supposed to be requested from the same origin, meaning from https://forismatic.com
It works with JSON because JSON works in a bit different way, but for the normal API call to work, someone on the API server would have to allow your website's origin for it to be able to make secure calls to the server.
You can try using JSONP for the request and see if it helps.
I'm trying to send a PUT-request to a Philips Hue bridge, so I can change the current state in which the lamp is. I do this from a webserver on my PC. With CORS I already managed to send GET and POST- request, but if I send a PUT I get an error that tells "method not found in Access-Control-Allow-Methods". I'm pretty sure that would make no sense to block just that method.
I'm using that code to do so, it is the same as the code for GET and POST, just the if clause is not needed.
var lightReq = new XMLHttpRequest();
if ("withCredentials" in lightReq) {
lightReq.open('PUT',stringChange,true);
if (value == false) {
lightReq.send("{\"on\":true}");
}
else {
lightReq.send("{\"on\":false}");
}
}
Maybe someone had a similar problem and got a solution, or there are steps I should check. I'm glad for every help.
EDIT:
Here is a screenshot of the header, it shows that the PUT-method should be accepted.
EDIT2:
For roryhewitt here is what you asked for, i think:
Best Regards,
Adrian
It looks from your screenshot as if that's the response to a POST request (I'm looing at the Anfragemethode field)?
Most of those CORS response headers (except ACAC) should only be returned in the response to a preflight OPTIONS request - they have no 'meaning' if they are returned in the response to any other request. That's the 'fault' of the bridge, though, not of anything you're doing in the browser code.
Anyway, when your JS code makes a PUT request via XMLHttpRequest, if you look at the network traffic from your browser, you should see an OPTIONS requests (CORS preflight) followed by your PUT request. If you only see the OPTIONS request, can you provide the response headers for that request?
I'm developing a Javascript app and I need to use the Mediafire REST API to upload a file. (See upload ducmentation here).
Following this MDN tutorial, and some research, I've written the code below, but it seems it's not working... Note that I don't need for the moment to control the progress and so on, I only want to do the most basic upload operation possible...
Also note that I could a different code, and even jQuery or other (free) libraries, so if you have a better code to upload a file I'd be really grateful...
var controller = this;
var file = $("#file").get(0).files[0];
//The file is correctly retrieved here...
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://www.mediafire.com/api/upload/upload.php?session_token=' + controller.sessionToken.token);
//(The session_token is valid)
xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.setRequestHeader('x-filesize', file.size);
var reader = new FileReader();
reader.onload = function (evt) {
var uInt8Array = new Uint8Array(evt.target.result);
//It seems that here the ArrayBuffer is read correctly,
//and I converted it to a ArrayBufferView because Chrome suggested it...
xhr.send(uInt8Array);
};
reader.readAsArrayBuffer(file);
I can't tell the concrete error, I only know that nothing is happens... but maybe looking at the code you can see some obvious error... The only thing I see is this in Chrome's console:
Note: I know the quality of this question is not the desired and it's TOO vague, but I tried to do my best taking into account that I'm completely new to ALL these technologies...
The presence of an OPTIONS request and the presence of specific headers in the OPTIONS request indicates that your POST request is a cross-domain request. The user agent, following the CORS spec, is first sending an OPTIONS request. This is also called a preflight request, and it is sent, in your case, due to the non-standard header you are including (x-filesize) and the fact that the Content-Type is not form-encoded, MPE, or text/plain. You can either deal with the OPTIONS request server-side, or make appropriate changes to your request so that a preflight is not required. Either way, you are going to have to deal with CORS requests server-side since you are apparently making a cross-domain request. You can read more about CORS in this excellent MDN article.
P.S. Why are you using FileReader here? Just send the File object via XHR, or, better yet, append the File to a FormData object and send that.
Access to restricted URI denied" code: "1012 [Break On This Error]
xhttp.send(null);
function getXML(xml_file) {
if (window.XMLHttpRequest) {
var xhttp = new XMLHttpRequest(); // Cretes a instantce of XMLHttpRequest object
}
else {
var xhttp = new ActiveXObject("Microsoft.XMLHTTP"); // for IE 5/6
}
xhttp.open("GET",xml_file,false);
xhttp.send(null);
var xmlDoc = xhttp.responseXML;
return (xmlDoc);
}
I'm trying to get data from a XML file using JavaScript. Im using Firebug to test and debug on Firefox.
The above error is what I'm getting. It works in other places i used the same before, why is acting weird here?
Can someone help me why it's occuring?
Update:
http://jquery-howto.blogspot.com/2008/12/access-to-restricted-uri-denied-code.html
I found this link explaining the cause of the problem. But I didn't get what the solution given means can someone elaborate?
Another possible cause of this is when you are working with a .html file directly on the file system. For example, if you're accessing it using this url in your browser: C:/Users/Someguy/Desktop/MyProject/index.html
If that then has to make an ajax request, the ajax request will fail because ajax requests to the filesystem are restricted. To fix this, setup a webserver that points localhost to C:/Users/Someguy/Desktop/MyProject and access it from http://localhost/index.html
Sounds like you are breaking the same origin policy.
Sub domains, different ports, different protocols are considered different domains.
Try adding Access-Control-Allow-Origin:* header to the server side script that feeds you the XML. If you don't do it in PHP (where you can use header()) and try to read a raw XML file, you probably have to set the header in a .htaccess file by adding Header set Access-Control-Allow-Origin "*". In addition you might need to add Access-Control-Allow-Headers:*.
Also I'd recommend to replace the * in production mode to disallow everybody from reading your data and instead add your own url there.
Without code impossible to say, but you could be running foul of the cross-site ajax limitation: you cannot make ajax requests to other domains.