I have a server running serving a HTML page and would like to serve an image residing in a local drive in Linux. I read that I can get that to work with appending file://... However, it doesn't seem to work in my case and I am suspecting that it might not work in my machine (Ubuntu 18.04). There's no error arose, just the img doesn't seem to find the image.
<img src="file:///home/my_user/my_picture.png">
Image result from code snippet above:
In this thread, I found an answer saying that the modern browser doesn't allow to serve local file for security reason.
If this is the case, is there any alternative for this?
I am thinking of passing the image byte data to the client and let the client-side javascript construct the image. But, my concern is the performance issue when there are a lot of image to be transferred. Also, I think it's quite ugly since the client is guaranteed to be in the same machine as the server.
The file:/// is for local files - that is the files in the computer where the browser runs.
If you want to load the files which are not in your public folder of the server,
You can mount the image folder inside the public folder
Create a route in your server which would resolve the image requests to the image folder
If you're loading imgs with the file:/// protocol, those files are on the client-side machine, not your server machine. And you wouldn't know the path of an image on the client-side machine, because every client's machine is different.
Then if the image that is yours, not the client's, you obviously have to somehow transfer it to them, even if there're abandon, or just 1 image.
Of course, you could optimize the transferring process with variant methods, like transferring base-64 byte data, shrink the size of the images, use different servers to transferring images than the code server, etc. But one way or another, you have to somehow transfer it to them.
the client is guaranteed to be in the same machine as the server
How could a client be guaranteed to be in the same machine as the server? Is it an app you deliberately downloaded? If it's a browser, it can be any arbitrary site on the internet. So your sentence is not in the context of the browser.
If you want to read the client's images, you have to let them select which image they allowed you to read, via File Reader, try the snippet below.
function showpreview(e) {
var reader = new FileReader();
reader.onload = function (e) {
document.querySelector('img').src = e.target.result;
}
//Imagepath.files[0] is blob type
reader.readAsDataURL(e.files[0]);
}
<img style="width: 100vw" src="" alt="">
<input type="file" onchange='showpreview(this)'>
Related
I want to display an image file from a local folder in JavaScript (p5.js). Every time I try I get: Access to image at "XXXXX" from origin "null" has been block by CORS policy: The response is invalid.
The HTML, js and images are all inside a file tree, inside the media server's project folder.
They HAVE to be run locally. Running from any other location than the folder they are in is not an option (referring to a lot of answers talking about running a web server.
function setup() {
createCanvas(96, 192);
img = loadImage('images/square1-01.png'); // Load the image
}
function draw() {
image(img, 0, 0);
}
//ALSO TRIED
img = loadImage('file://images/square1-01.png'); // Load the image
The above text is a super simplified version that I isolated from the main file so I could run it standalone, just so I could get to the point of getting an image, before I started adding in the other layers of complexity.
Thus the layout is entirely from a tutorial.
Relevant files are:
.../web/d3test.html
.../web/d3test.js
.../web/images/square1-01
.../web/images/square2-01
.../web/images/square3-01
JavaScript is blocked from accessing local files like this, for security reasons. You wouldn't want every website snooping through the files on your hard drive. That's what's causing your error.
Instead of accessing files on your local hard drive, you need to access files from a web server. You could upload your your sketch (along with your images) to a web host. Shameless self-promotion: here is a tutorial that introduces some options for hosting.
You could also use the P5.js editor. This is a free editor for P5.js that automatically uploads everything to a web host. Your could should work fine there.
You could also run your own local web server.
If you really, really, really need to run this without a web server, then you can try the File API described in this answer or find a setting in your browser described in this answer.
I've built a simple html page with javascript in a separate file, called on a button press.
I've opened the html file in chrome, and the path resembles: file:///home/tom/projects/index.html
The javascript needs to read a JSON file (file:///home/tom/projects/mydata.json) which is in the same directory, using a hardcoded path.
I'm really struggling to do this. As I understand, this is because I'm using client side js (meaning I can't use the fs library for example), which is limiting my options.
According to the question here, I can't load the file if I use the URL in the format: file:///home/to.... as it gives me the error:
Cross origin requests are only supported for protocol schemes: HTTP, data, chrome, chrome-extension, https.
If I start an HTTP-server, as the answer suggests, I can use server-side modules, but if possible I would like to avoid this.
I've noticed many answers that suggest using a dialog box like this:
var selectedFile = document.getElementById('input').files[0];
function readFile (file_path) {
var reader = new FileReader();
reader.readAsText(file_path);
console.log(reader.substring(0, 100));
};
but I can't make this work with a path in the form: file:///home/tom/projects/mydata.json
Is there a way to load a .json file from a file:///home/to.... format URL using client-side javascript, with a hardcoded path (ie not asking the user to select the file from a selection box)?
This is a deliberate security restriction, to stop a user from being given, and then opening, a HTML page which then tries to read their disk.
Run your page in a webserver (as that question suggested) then you can either load the JSON from a URL (e.g. something like http://localhost/projects/mydata.json) using JavaScript, or use a server-side language to fetch it and display it inside the rendered HTML. Either way will work, the first way is probably simpler and closest to what you've got now.
It's always far better to serve HTML pages from a HTTP server, the way it's intended to be.
I have a file which is split up into multiple parts on the server side. The complete file is huge, it can be 10 or more gigabytes in size (that is the reason for splitting it in the first place).
The file is in a specific format, and it has to be processed on the client side before being downloaded.
Now, I know that I can download into a Blob to the client side, do the processing, then download Blobs from there with this approach: JavaScript blob filename without link
The problem here is that I would need to construct a single huge blob from all the file parts on the client side, which I do not want, because it will probably exceed RAM limitations rather quickly.
I would like to download each part of the file individually and then process it and download the "partial" blob. That means that I would need to start a download and then piece by piece add blobs to it until the download is complete.
Is there any possibility of doing this? How? I know that mega.co.nz does something similar with file downloads where they process the file on the client side first (for decryption). Are they using such techniques?
You can save the downloaded parts to localStorage. You will have to serialize each part into a string first; then you can call localStorage.setItem. Your code might look like this:
localStorage.setItem('download-part-' + chunkIndex, chunkDataAsString);
chunkDataAsString = ''; // let the garbage collector collect the large string
I'm working on a website where the users can solve a practice exam.
My client wants to include a div next to the exam with a PDF viewer.
The idea is that the user can select a PDF file from his local machine and it will be loaded into the PDF viewer next to the exam.
I made it work using pdf.js and pdfobject.
The problem is that both options require the PDF file to be uploaded to our server.
Due to intellectual property law, that is unacceptable to our client.
They want the PDF file to be embeded without uploading it to our server. So it has to be loaded directly from the user's machine.
I found that it can't be done. All the plugins I tried require a virtual url, and will not accept a physic one (file:///local/path/file.pdf).
I don't want to just tell my client "it can't be done". I would like to know a technical explanation of why can't it be done.
If somebody knows a way to make it work it would be better!
This is a security policy. Issues it defends against include:
Allowing sites to detect your operating system by checking default installation paths
Allowing sites to exploit system vulnerabilities (e.g., C:\con\con in Windows 95/98)
Allowing sites to detect browser preferences or read sensitive data
Try to load it in a <iframe> with the URL of the PDF as src. But it might fail because of the client's browser's security policy. So this is brittle at best.
Maybe you can use HTML5 localstorage to upload the file to a "safe" location ("safe" as far as the browser is concerned).
PDFJS.getDocument() supports "a typed array (Uint8Array)
already populated with data or parameter object." So upload to local storage, get the document as bytes from there and then pass it to pdf.js.
Related:
https://hacks.mozilla.org/2012/02/saving-images-and-files-in-localstorage/
You might be able to do this, if the browser supports it. Take a look at the FileReader object. If the user's browser supports that, you can allow the user to select a file and reference that file in code. Something like this works for me in Firefox:
$('input[type=file]').change(function () {
if (window.FileReader) {
var input = this;
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$(input).next('iframe').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
});
So if you have a input type="file" followed by an iframe then this will allow the user to select the file, and once it's selected it will load it into the iframe as a base64-encoded data URI.
Example here.
Is there a reason PNG and JPG images would be embedded in a JavaScript file like this:
// Template/Image data
var LOGO = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4 etc";
var BACKGROUND = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIA etc";
If I remove these portions and call files stored on a server instead, will there be a performance penalty or something? The only thing I can think of is Apache serving extra requests for those images, but I'm not even sure it works that way. Is there anything else?
Its mostly convenience and to avoid preloading the images. Since no additional requests have to be sent to the server to display the image, the image will be displayed as soon as you set this value to the src attribute.
In terms of amount of data downloaded, this technique avoids the extra overhead of additional requests but the total sizes downloaded could be a bit larger since the entire image data is encoded in base64. In applications where you might have lots of such images preloading could be a better.
A request to that image file takes longer than showing the image from the binary. So your page has saved some requests :)