how to properly load an image with p5.js? [duplicate] - javascript

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);
}

Related

403 error when accessing an external image URL on an internal website

I've been working on this internal web app that allows the users to click on a button to see an image. Pretty straight forward.
<img id="swatchimage" width="600" height="600" src="" />
The image needs to be linked from an external website. The piece of javascript that does that is:
$("#swatchimage").attr("src", fileURL);
One of the URLs look like this:
If you try to access the image above in a browser it works without a problem.
When accessing it from the internal app ( IP: 192.168.110.15 ) then the server returns 403 error.
The same files are used in the main website, so I don't think it's about the hot linking protection (which i tried to disable too, to no avail).
Is there some restriction that I'm not aware of when linking these kind of resources?
I think I found the problem:
The server (cdn.palmcentre.co.uk) is not sending an Access-Control-Allow-Origin header in the response, so you can't use JavaScript to fetch it.
However, this is not a 403. Here's a screenshot of the error I get:
Also, what you're trying to do is not to fetch the image, but modify the src attribute of an <image> element, which should be allowed.
This makes me think that the error you're getting is because jQuery is trying to fetch the image, and failing, but I'm not sure.
Try doing this instead:
document.getElementById("#swatchimage").src = fileURL;
It seems I have found the solution.
It was puzzling indeed, because i knew that CORS would not be at play here. It was just another image URL that was requested from an HTML tag. So it shouldn't have behaved in such way.
Notwithstanding the help received, for which I am grateful, it seems that the issue was in fact a hot linking protection that was in place.
But it was not from the server itself or from the script but rather from the CloudFlare cache itself.

canvas getImageData isn't working

I have tried to getImageData but in the console I see this error:
Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
at HTMLImageElement.img.onload (file:///C:/Users/HOME/Desktop/programmi/HTML-Javascript/caso/graphic/imgData/arc/main.js:16:17)
This is my JavaScript and HTML code:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
width = canvas.width = 434,
height = canvas.height = 362;
var img = new Image();
img.src = 'https://cdn.pixabay.com/photo/2017/02/26/12/27/oranges-2100108_640.jpg';
//img.crossOrigin = 'Anonymous';
img.onload = function() {
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(10, 10, 11, 11);
console.log(data)
};
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas id='canvas'></canvas>
<script type="text/javascript" src='main.js'></script>
</body>
</html>
Let me guess ... you're using Google Chrome as your browser. Which is the most problematic browser for this issue.
The issue centres upon what is known as cross-site security. in short, modern browsers are designed to prevent cross-site content from being loaded into a browser, except under special conditions, in part to stop malicious code being injected into web pages that you load.
This extends to images and HTML5 canvas data. The reason being, that some sneaky individuals discovered, early in the days of the HTML5 canvas being provided, that they could use it to provide an image snapshot of your current browser contents, and send that snapshot back to be perused at leisure. If you were browsing your bank's website at the time, and engaging in sensitive financial transactions online, whoever used this technique would quickly be able to find out about your finances, and possibly even pose as you to raid your account.
That's one of the reasons restrictions on cross site content were introduced.
Now, of course, there are legitimate reasons for having cross-site content. Such as having one's fonts or images stored in a separate repository. Trouble is, the cross-site restrictions impact upon legitimate uses as well as illegitimate ones.
Consequently, in order to use images cross-site, you have to do so in conformity with the CORS protocol. But, to do this, you need your images to be provided by a web server that's set up to handle CORS transactions. Simply setting the img.crossOrigin property of an Image object to "anonymous" won't work on its own: you need the server that's sending the images, to be set up to respond to the pre-flight options request that your browser will send, before allowing the image to be treated as acceptable from a security standpoint.
Which means, that to solve your problem, you need either, to:
[1] Install a local web server to perform this task for you - this option involves much tedium reading the web server manual, in order to set the server up properly, and much editing of configuration files;
[2] Write your own server to run under node.js or similar - this option involves even more tedium learning how to write your own web server, and make that server handle CORS transactions properly.
Now, if you're testing code offline in the "old school" manner, Firefox will let you access images from the same directory as your code, via the file:// protocol, and won't complain. Firefox apparently has enough intelligence to realise that an image being extracted from the same directory of your hard drive as your web page, constitutes a same-origin image.
If, however, you're using Google Chrome, it won't. At least, not unless you run it using special command line parameters. Even then, Chrome has a propensity to throw temper tantrums when asked to handle this sort of request. It's an issue I wrestle with frequently, and though some might be tempted to tell me to do my testing in Firefox to avoid these woes, Chrome's internal debugger is, for me at least, far more pleasant to use than Firefox's debugger, which, in my current Firefox installation, crawls like a snail on Mogadon, and exhibits a friendliness and smoothness of use reminiscent of a cocaine-soaked pit viper.
So, if you're using Chrome, because like me, you like its internal debugger, you're stuck with the two options I've given above. Either install a web server (Apache, Nginx, take your pick) or install Node.js and write your own. Neither option is easy.

gapi.client.load not working

I have the following code, which is supposed to be a simple example of using the google api javascript client, and simply displays the long-form URL for a hard-coded shortened URL:
<script>
function appendResults(text) {
var results = document.getElementById('results');
results.appendChild(document.createElement('P'));
results.appendChild(document.createTextNode(text));
}
function makeRequest() {
console.log('Inside makeRequest');
var request = gapi.client.urlshortener.url.get({
'shortUrl': 'http://goo.gl/fbsS'
});
request.execute(function(response) {
appendResults(response.longUrl);
});
}
function load() {
gapi.client.setApiKey('API_KEY');
console.log('After attempting to set API key');
gapi.client.load('urlshortener', 'v1', makeRequest);
console.log('After attempting to load urlshortener');
}
</script>
<script src="https://apis.google.com/js/client.js?onload=load"></script>
except with an actual API key instead of the text 'API_KEY'.
The console output is simply:
After attempting to set API key
After attempting to load urlshortener
but I never see 'Inside makeRequest', which is inside the makeRequest function, which is the callback function for the call to gapi.client.load, leading me to believe that the function is not working (or failing to complete).
Can anyone shed some light on why this might be so and how to fix it?
Thanks in advance.
After spending hours googling the problem, I found out the problem was because I was running this file on the local machine and not on a server.
When you run the above code on chrome you get this error in the developer console "Unable to post message to file://. Recipient has origin null."
For some reason the javascript loads only when running on a actual server or something like XAMPP or WAMP.
If there is any expert who can shed some light to why this happens, it would be really great full to learn.
Hope this helps the others noobies like me out there :D
Short answer (http://code.google.com/p/google-api-javascript-client/issues/detail?id=46):
The JS Client does not currently support making requests from a file:// origin.
Long answer (http://en.wikipedia.org/wiki/Same_origin_policy):
The behavior of same-origin checks and related mechanisms is not well-defined
in a number of corner cases, such as for protocols that do not have a clearly
defined host name or port associated with their URLs (file:, data:, etc.).
This historically caused a fair number of security problems, such as the
generally undesirable ability of any locally stored HTML file to access all
other files on the disk, or communicate with any site on the Internet.

How can I test if a user viewing my website can not see some content, and how can I make sure my test works?

I'm using code similar to below:
var image = new Image();
image.src = "http://youtube.com/favicon.ico";
image.onload = function(){
// The user can access youtube
};
image.onerror = function(){
// The user can't access youtube
};
Which I found here: Detecting if YouTube is blocked by company / ISP
To test if a user has access to youtube/facebook/twiter, so when I try to embed a video, or a like button. I know if the user can see it. At my workplace whenever I go to a website that uses a like/tweet button etc, I see a small portion of an ugly page telling me that the content is blocked on our network. I don't want the people visiting my site to see this.
The above code works fine for me on my network. But what methods can I use to test it to make sure it will work for everyone, and if it doesn't what code would, as every workplace/network blocks content differently.
Thanks for any answers.
What you're doing is the best you can get. You answered yourself partly when you mentioned that "every workplace/network blocks content differently". For all you know, the mediating proxy could return a valid webpage or image when you try to request a blocked resource. This wouldn't be an error condition but obviously it also wouldn't be the content that you were expecting. There is no "sure" way to tell if the returned content is correct or not.
if the image is loaded, you can check the width/height of the loaded image against the original size of the requested image.(Should be 16/16 for http://youtube.com/favicon.ico )
This is also described in the linked Topic
Detecting if YouTube is blocked by company / ISP
I dont think that the blocking application will request the original ressource to lookup, what size it will have.

Can I load a web worker script from an absolute URL?

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 =]

Categories