I try to load a json file from a server with XMLHttpRequest.
But I only get status==0 and the chrome dev console says: "(canceled)"
I can reproduce this with this (simplified) code:
var httpReq = new window.XMLHttpRequest();
httpReq.onreadystatechange = function(data) {
if (httpReq.readyState == 4) {
alert(httpReq.status);
}
}
httpReq.open("GET", "http://dl.dropbox.com/[...]/data.json");
httpReq.send(null);
This code stops working, as it is in the extension context.
The same function is also used to load files from an other server (also crossdomain), without any problem.
Here is the manifest part:
"permissions": [ "http://theOtherWorkingServer.com/*", "http://dl.dropbox.com/*", "https://dl.dropbox.com/*" ],
I've read a lot about this problem, but found no working solution.
(The main page is not reloading and also not redirected at this time)
Any suggestions??
The error you're getting is a sign that a redirect was performed, to an URL which does not match any of your declared permissions.
To verify my statement, add the *://*/* or <all_urls> permission to the manifest file, and you will notice that the request completes successfully.
To determine which redirects are followed, follow the following steps:
Open the developer tools, go to the Network tab.
Paste the URL in the omnibox, and hit enter
Read the URLs in the developer tools.
As you can see in the previous picture, dl.dropbox.com actually redirects to dl.dropboxusercontent.com. This domain has to be added to the permission section of your manifest file, to fix the problem:
"permissions": [
"http://theOtherWorkingServer.com/*",
"*://dl.dropbox.com/*",
"*://dl.dropboxusercontent.com/*"
],
(the the wildcard at the scheme matches http and https - see match patterns)
Related
I am having one executable URL ..when I hit that URL using GET type request that URL should return me Array in Javascript...
I have created one doGet() in remote server which returns JSON.stringfy(array);
I tried this code...can anyone tells me how I can get that array?
fetch(myUrl,{method:'get',headers:{'content-type'-'application/x-www-form-urlencoded'},
mode:'no-cors'}).then(function (response){ console.log(response);
});
You need CORS permission to read data from a different origin so do not set mode:'no-cors'.
If you are writing an extension page — not a content extension script — such as a background page, popup, or options page then you can request cross-origin permissions:
By adding hosts or host match patterns (or both) to the permissions
section of the manifest file, the extension can request access to
remote servers outside of its origin.
{
"name": "My extension",
...
"permissions": [
"https://www.google.com/"
],
...
}
Aside: You are making a GET request so you have no request body and so shouldn't describe the type of content in the request body. 'content-type'-'application/x-www-form-urlencoded' is nonsense.
I wrote an extension that works both on Firefox and on Chrome. That extension injects some code on the page that also does a Get - Request on the same site.
I am on https://example.com/Posts/1234 and try to call another url from the same host:
var docUrl=document.location.href;
$.get(docUrl + '/mentionable.json?q=test', function (response) {
// do something
});
(So the complete url called is https://example.com/Posts/1234/mentionable.json?q=test)
In the chrome extension this works just fine. When I try to run the same code as a Firefox web-extension instead I retrieve a 401 unauthorized response. So my guess would be that chrome sends the authorization-cookie from the current visited site while Firefox does not.
Any way to tell Firefox to use the current authorization?
I found the solution. Firefox requires the following entry in the permissions of the manifest.json:
"https://*/*"
(or the URL you want to connect to) even if it's the same host as the site the extension-js is on. Chrome works without this entry.
I'm building an app in witch the user see a set of downsized images and than press " ok" for the app to download all of the original files, put them into a zip file and send the zip file.
the app is using polymer, polymerfire, firebase (including the storage).
during the upload of the images i save in the database both the download url and the storage reference for both the original file and the downsized one.
when i put the download url in the iron-image element to show the images in the browser everything works perfectly, the downsized images are shown on the screen.
When i try to download the fullsize images via XMLHttpRequest() i get the Cors error.
I can't understand why, both request are coming from the same app, why two different cors response?
here is the code for the XMLHttpRequest() (mostly copied from the firebase documentation):
for (var z = 0; z < visita.immagini.length; z++) {
var immagine =visita.immagini[z]
var storage = firebase.storage();
var pathReference = storage.ref('immagini/'+ immagine.original.ref);
pathReference.getDownloadURL().then(function(url) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function(event) {
var blob = xhr.response;
console.log(blob);
};
xhr.open('GET', url);
xhr.send();
}).catch(function(error) {
console.log(error);
});
}
and here is the error response:
XMLHttpRequest cannot load ***** [image link]******. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access.
note that if i copy the ***** [image link]****** and put in another tab of the browser i can see without problems.
I finally found some information on CORS + storage as asked. Check out the firebase docs on storage here: https://firebase.google.com/docs/storage/web/download-files#cors_configuration.
Firstly, you will need gsutil (https://cloud.google.com/storage/docs/gsutil_install).
Then make a file named cors.json somewhere in your project with the following content:
[
{
"origin": ["*"],
"method": ["GET"],
"maxAgeSeconds": 3600
}
]
Finally run:
gsutil cors set cors.json gs://<your-cloud-storage-bucket>
These steps worked for me!
This is also answered here: Firebase Storage and Access-Control-Allow-Origin, which I found after answering.
The section on headers in the Firebase “Deployment Configuration” docs says that to enable cross-origin requests for images, you must add to your firebase.json something like this:
"headers": [ {
"source" : "**/*.#(jpg|jpeg|gif|png)",
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
} ]
when i put the download url in the iron-image element to show the
images in the browser everything works perfectly, … When i try to
download the fullsize images via XMLHttpRequest() i get the Cors
error. I can't understand why, both request are coming from the same
app, why two different cors response?
Because browsers block cross-origin XHR requests unless the server receiving the requests uses CORS to allow them, by responding with an Access-Control-Allow-Origin: * header.
note that if i copy the ***** [image link]****** and put in another
tab of the browser i can see without problems.
That’s expected. When you put a URL into your browser’s address bar, it’s not a cross-origin request—instead it’s just you navigating directly to a URL.
But when you put that URL into the JavaScript for a Web application running at some origin on the Web, then when that request is sent, it’s not you navigating directly to the URL but instead it’s some Web application making a cross-origin request to another Web site.
So browsers by default block such cross-origin requests from frontend JavaScript code. But to opt-in to receiving such requests, a site can include the Access-Control-Allow-Origin header in its response to the browser. If the browser sees that header, it won’t block the request.
For more details, see the HTTP access control (CORS) article at MDN.
I wrote a chrome extension for a specific website. If the extension is installed and I navigate to that site "example.com", my extension calls the following method:
var search="john";
$.get("https://www.example.com/complete/search?q="+search, function (data) {
console.log(data);
});
That works just fine.
Now I have to call the same method from within the options-page of that extension. When I do that, I receive the following error:
XMLHttpRequest cannot load
https://www.example.com/complete/search?q=John. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
I understand why this happens but have to find a way to get around this. My idea is to trigger the Extension-Script to call the method and then return the results to the options page. I expect, chrome.runtime.sendMessage() isn't help here.
Needless to say: That domain is not hosted by me, so I can't just change the header.
The error indicates it's not an actual options page: you're opening it (possibly accidentally) through a local webserver (origin: http://localhost/) instead of opening a page packaged with the extension.
You need to add your page (say, options.html) to your extension's folder
You need to add it to the manifest like "options_page": "options.html" or better yet with options_ui
You need to reload the extension to apply the manifest change
You need to open it through the extension, e.g. through chrome://extensions or the context menu of your extension's button (if any)
I know that this has been talked about many times here, and I have read most of these threads but I can't seem to get my script working.
Problem is that I am trying to use bitly api to shorten urls in google chrome extension. I am saving users login and apiKey in localstorage and before I do so I validate them.
The code to do so is:
$.ajax({
url:"http://api.bit.ly/v3/validate",
dataType:'jsonp',
data:{
login: login,
apiKey: apiKey,
x_login :"test",
x_apiKey :"test"
},
success:function (jo, textStatus, jqXHR) {
if (jo.status_code == 200) {
setItem('dg_BitlyApiKey', apiKey);
setItem('dg_BitlyLogin', login);
alert('Saved');
} else {
alert('Incorrect login and/or apiKey!')
}
}
});
I do have my permissions set to "permissions": ["tabs", "notifications", "http://*/*", "https://*/*"] but I still keep getting:
Refused to load script from 'http://api.bit.ly/v3/validate?callback=jQuery17204477599645033479_1334062200771&login=&apiKey=&x_login=test&x_apiKey=test&_=1334062201506' because of Content-Security-Policy.
The script itself works outside the extension so I assume the problem isn't within the script but with the permissions.
What am I doing wrong here?
The problem is that you aren't really doing a XHR request, you're doing a JSONP request on an insecure HTTP resource. See the question How to load an external JavaScript inside an extension popup and the related Chromium bug report.
Yeah, we're no longer allowing insecure scripts in extensions. If you load a script over HTTP, an active network attacker can inject script into your extension, which is a security vulnerability.
JSONP operates by dynamically adding a new script tag into your page and then executing the contents. In your case, the script resource is fetched over HTTP (instead of HTTPS). If your extension uses version 2 of the extension manifest, its background pages cannot fetch non-HTTPS scripts.
Solution: If you use the Bitly API over HTTPS, I believe that will fix your issue. Send your Ajax call to https://api-ssl.bitly.com/v3/validate (instead of your current value of http://api.bit.ly/v3/validate)
You need to package your app/extension for cross domain requests to work. A hosted application will not be able to do cross domain requests. See:
Cross-Origin XMLHttpRequest in chrome extensions
To make Cross-Origin Requests in Chrome Extension you need to Avoid Cross-Origin Fetches in Content Scripts.
Full answer you can found in
https://stackoverflow.com/a/56929473/3680164
Or in the documentation
https://www.chromium.org/Home/chromium-security/extension-content-script-fetches