I haven't been able to get something like this to work:
var myWorker = new Worker("http://example.com/js/worker.js");
In my Firebug console, I get an error like this:
Failed to load script:
http://example.com/js/worker.js
(nsresult = 0x805303f4)
Every example of web worker usage I've seen loads a script from a relative path. I tried something like this, and it works just fine:
var myWorker = new Worker("worker.js");
But what if I need to load a worker script that's not at a relative location? I've googled extensively, and I haven't seen this issue addressed anywhere.
I should add that I'm attempting to do this in Firefox 3.5.
For those that don't know, here is the spec for Web Worker:
http://www.whatwg.org/specs/web-workers/current-work/
And a post by John Resig:
http://ejohn.org/blog/web-workers/
Javascript, generally, can't access anything outside of the url that the javascript file came from.
I believe that is what this part of the spec means, from: http://www.w3.org/TR/workers/
4.2 Base URLs and origins of workers
Both the origin and effective script origin of scripts running in workers are the origin of the absolute URL given in that the worker's location attribute represents.
This post has a statement about what error should be thrown in your situation:
http://canvex.lazyilluminati.com/misc/cgi/issues.cgi/message/%3Cop.u0ppu4lpidj3kv#zcorpandell.linkoping.osa%3E
According to the Web Worker draft specification, workers must be hosted at the same domain as the "first script", that is, the script that is creating the worker. The URL of the first script is what the worker URL is resolved against.
Not to mention...
Just about anytime you have a Cross-Origin Restriction Policy, there's no counterpoise to the file system (file://path/to/file.ext) - Meaning, the file protocol triggers handling for this policy.
This goes for "dirty images" in the Canvas API as well.
Hope this helps =]
Related
I'm trying to load an image called "border.bmp" so that I can use it as a texture for WebGL. Here's how I reference the image.
var img;
function preload() {
img = loadImage("assets/border.bmp");
}
I then get this error in the console.
Access to Image at 'file:///C:/P5.js/empty-example/assets/border.bmp' from
origin 'null' has been blocked by CORS policy: Invalid response. Origin
'null' is therefore not allowed access.
What is this error message? What does it mean? How do I load the image?
The comment by gman and the answer by Dale are both correct. I highly recommend you take the time to understand exactly what they're saying before you downvote or dismiss them.
CORS stands for cross-origin resource sharing, and basically it's what allows or prevents JavaScript on one site from accessing stuff on another site. A quick google search of "JavaScript CORS" or just "cors" will give you a ton of information that you should read through.
So if you're getting a CORS error, that means that the site that holds your image is not letting the site that holds your code access the image. In your case, it looks like you're loading stuff from a file: URL, which is not being loaded from a server. That's what the Origin null part of the error means.
So, step one is to listen to gman's comment and run your sketch from a local webserver instead of using a file: URL. His comment already contains links explaining how to do that, or you could use the P5.js web editor or CodePen or any other basic web host.
The most common setup is to include the image files in the same server as the code, so that should be pretty much all you need to do. But if you're storing the images at a different URL than the code, then step 2 is to follow Dale's answer and setup your image server to allow requests from your code server.
While the following doesn't directly answer the OP question, it can help others, like me, that ended up here searching for P5.JS CORS.
To bypass CORS restrictions simply add the blocked URL after https://cors-anywhere.herokuapp.com, i.e.:
var = 'https://cors-anywhere.herokuapp.com/http://blocked.url'
P5.JS Example:
Lets say you want to load a remote mp4 video (it can be any file-type) using P5.JS from a server that doesn't have CORS enabled, for these situations, you can use :
var vid;
function setup() {
vid = createVideo(['https://cors-anywhere.herokuapp.com/http://techslides.com/demos/sample-videos/small.mp4'], vidLoad);
}
// This function is called when the video loads
function vidLoad() {
vid.play();
}
UPDATE:
The demo server of CORS Anywhere (cors-anywhere.herokuapp.com) is meant to be a demo of this project. But abuse has become so common that the platform where the demo is hosted (Heroku) has asked me to shut down the server, despite efforts to counter the abuse (rate limits in #45 and #164, and blocking other forms of requests). Downtime becomes increasingly frequent (e.g. recently #300, #299, #295, #294, #287) due to abuse and its popularity.
To counter this, I will make the following changes:
The rate limit will decrease from 200 (#164) per hour to 50 per hour.
By January 31st, 2021, cors-anywhere.herokuapp.com will stop serving as an open proxy.
From February 1st. 2021, cors-anywhere.herokuapp.com will only serve requests after the visitor has completed a challenge: The user (developer) must visit a page at cors-anywhere.herokuapp.com to temporarily unlock the demo for their browser. This allows developers to try out the functionality, to help with deciding on self-hosting or looking for alternatives.
CORS Stands for Cross-origin resource sharing. By default WebGL will block any resource (images, textures, etc) from any external origin. WebGL thinks the local resource is from an external origin.
You can bypass this by using img.crossOrigin = "";
I'm not an expert in webGL, all this information was found here
If you want to load local images in P5, you can use the drawImage() function of the canvas instead of image() function of the P5.js
let img;
function setup() {
createCanvas(windowWidth,windowHeight);
img = new Image();
img.src = "assets/smiley.png";
}
function draw() {
drawingContext.drawImage(img,mouseX,mouseY);
}
I would like my web app to be promoted for Add to Home Screen for users on Android+Chrome. (inspired by : Chromium Blog entry)
To do this I need a Service Worker running, even a dummy one. (Chrome needs the Service Worker as proof that I'm serious about web apps)
So I've created a dummy Service Worker with no content. It gets served with the correct no-cache headers, served over HTTPS, and is scoped to the whole domain.
Thing work generally, however every time I try to create an audio element on the fly :
jQuery( '<audio><source src="/beep.mp3" type="audio/mpeg"></source></audio>' );
...my console shows some unhappiness (taken from Chrome Canary for better messaging from the service worker thread, but basically the same output is in Chrome current) :
Mixed Content: The page at 'https://my.domain.com/some/page' was loaded over HTTPS, but requested an insecure video ''. This content should also be served over HTTPS.
GET https://my.domain.com/beep.mp3 400 (Service Worker Fallback Required)
I suppose it's important to note that, obviously, I'm not retrieving the resource directly, just creating the element and letting the browser retrieve the MP3.
The MP3 does actually get fetched (I am able to run the .play() method on the audio element). It's just the errors in my console log are piling up and makes me suspicious of how reliable this approach is. Also, incidentally, in Canary (but not current) the failure will change my "HTTPS lock" indicator from green to "warning" (so, future problem).
The audio source is from the same domain as the page, and both are HTTPS. So the "Mixed Content" message from the service worker thread is strange; it references a video with '' as the url.
Question : Am I doing something wrong or is this a Chrome bug? Do I need more than a dummy (empty) service worker? If I'm doing something wrong, I would like to find a best-practice/long-term type solution rather than hack something together, but I'll take what I can get. ;)
it seems to be a bug. This is the issue on Google code:
https://code.google.com/p/chromium/issues/detail?id=477685
I have a Worker.js file and a Subworker.js file in my Scripts folder. No problem creating a worker, I can step through its code in the debugger; but when I want that worker to spawn a subworker, it isn't getting created, and I'm unable to step through the subworker code file in the debugger.
In myPage.htm script block:
var worker = new Worker("Scripts/Worker.js"); // Succeeds
In Worker.js script file:
var subworker = new Worker("Subworker.js"); //without the folder name FAILS
The IE10 developer tools Network console shows this:
URL....................Method...Result..Type.......................Received.......Taken......Initiator
/Scripts/Worker.js.....GET......200.....application/x-javascript...1.00KB..........<1ms......webworker
/Scripts/Subworker.js..GET......404.....text/html..................2.50KB..........239.29s...webworker
EDIT: Found the answer to the 404 error although still unable to instantiate the subworker:
var subworker = new Worker("..Subworker.js");
EDIT2: Also found that the following trick to cause the current version of a script to be used generates a 400 error:
var subworker = new Worker("..Subworker.js?version=2.0");
I'm in about the same boat.
My plan is to load a subworker from another doamin or file:// protocol because you cannot load one directly from a regular js script. I still need to test this, but I know that Workers/SharedWorkers are not subject to the normal Cross-Origin Restriction Policy, except** for when you're trying to load one (and hopefully only when doing this from a window script).
Another method is to use window.postMessage to forward messages to a Worker that it has created in the other window.
Alternatively, for my specific needs I am considering running a headless browser locally, a CDN, or a localhost "forever-server" with CORS enabled -- but this most likely still requires a window.postMessage().
Hope this helps, Tim!
Post back if you find an answer, eh?
HI, i got a simple html page, localy with an iframe. the iframe includes a generated page which got a javascript function. i know want to call that function. of course, im getting "permission denied". so since im new to js and all that stuff i dont know if it's actually possible to do that. give me some hints for searching or a nice solution.
i do cal lthe func like: parent.myiframe.myfunc();
I guess the page in the iframe resides on another server / domain. Modern browser do not allow "cross site scripting", see: http://de.wikipedia.org/wiki/Cross-Site_Scripting
If possible, move the site in the iframe to the same server. An alternative (workaround) would be to proxy the page on the local server, so that that for the client it seems to be loaded from the same domain.
Edit: This is also called a "Same Origin Policy". You can only call java script functions in a document that is:
from the same domain (www.mydomain.com)
from the same subdomain (mail.mydomain.com <- no go!)
both use the same port (p.Ex.
accessing a http://... document from
a http*s*:// document won't work).
There might be another workaround if you have access to the iframe's source:
Change the iframe domain to the same as the outer frame's, by applying:
document.domain = "domain.com";
in the iframe source (see http://ajaxian.com/archives/how-to-make-xmlhttprequest-calls-to-another-server-in-your-domain for more information).
Also there is a Draft for "Cross-Origin Resource Sharing" (http://www.w3.org/TR/cors/) that is already partially implemented in several browser, see: http://www.webdavsystem.com/ajax/programming/cross_origin_requests
We have gone through from all possible blogs of AMP but couldn't find any way to include custom JS in AMP. This blog(https://www.ampproject.org/docs/guides/pwa-amp/amp-as-pwa#extend-your-amp-pages-via-service-worker) indicates that we can add Custom JS in AMP with the help of Service worker but haven't describe how to do it.
Please let us know How to do it.
Edit:- After adding JS at the run time, it again show the same old error, Please have a look to the image
Note in the mentioned blog post that you can extend your AMP pages
as soon as they’re served from the origin
Having a service worker in itself doesn't exempt you from AMP restrictions. However if you install a service worker in your AMP page, you can then begin to use AMP as a (progressive) web app, with less restrictions. There are multiple patterns you can use - this article covers the major patterns and this Google Codelab shows you how to implement them.
Hope that helps!
EDIT:
Yeah, okay I see what you mean. You could accomplish that by adding this code to the service worker:
self.addEventListener('fetch', e => {
var url = new URL(e.request.url);
if(url.pathname.split('/').pop().endsWith('amp.html')) {
e.respondWith(
fetch(e.request).then(response => {
var init = {
status: 200,
statusText: "OK",
headers: {'Content-Type': 'text/html'}
};
return response.text().then(body => {
body = body.replace('</body>', '<script src="extra.js" async ></script></body>');
return new Response(body, init);
});
})
);
}
});
This will dynamically add the extra.js file to all the *amp.html pages that your app requests. I believe it will still validate, but I haven't tested it.
Note that this will only work when it's served from your origin (as opposed to the AMP Cache), because that's where your service worker has control.
This resource is where I found the code example (it has a soft paywall).
Let me know if it works! :)
#DavidScales's answer is great if you want to specifically include your custom JS through a service worker for some reason. You could also just include your custom JS in a hidden amp-iframe on the page. Note that all of your custom js would have to be changed to reference the parent, so that it can access the AMP page's DOM.
See this thread.
Also see this thread for how to access the AMP page from inside the iframe.
The amp-install-serviceworker component enables service worker installation via same origin or via the Google AMP Cache.
Note : Service Workers are currently available in Chrome, Firefox and
Opera.
How to use amp-install-serviceworker? CLICK HERE