Drag and drop upload image file size limit - javascript

I used to use a web hosting with cPanel and there is no problem with drag and drop image uploading ( every file is less than 2MB ).
The uploading method is like
<img src="data:image/jpeg;base64,xxxxxxx...">
and I post it on url into php to encode to a image file.
After I moved my website to another web hosting and some problem just happened with drag and drop uploading.
If any file size is larger than 730KB, the uploading will be fail.
I have google a lot, including modify php.ini like post_max_size, upload_max_filesize, even set ini_set('memory_limit', '256M') and ini_set('post_max_size', '8M') in php file, it's not working at all.

If your new hosting is not administrated by you, then they may have restricted the ability to set ini configs from the PHP scripts, and lowered the limit file uploads.
Also memory_limit is not the directive you need, is max_upload_size and post_max_size.
memory_limit limits the amount of RAM that PHP can consume before fatal erroring.

I have found where the problem is.
based on my uploading method is drag and drop image, i tried to count post length with using "alert(encode.length)" and i found that if length of every file is longer than 1,000,000, it will shows error.
so i tried to find the value 1,000,000 in phpinfo()
it's
suhosin.post.max_value_length
so in
/etc/php5/conf.d/suhosin.ini
i change it 1,000,000 to 10,000,000 and remove the mark then restart apache, it works fine now.

Related

Saving user uploaded image to folder and/or server

I have an app, that allows users to upload an image, crop it and with other data save it all as html file to be used as a footer for emails. The image is given to them as base64.
Howver turns out this is not supported by Outlook, since it doesnt accept b64 data as img source.
So my idea was to save the cropped image to a file, let's say /public/avatars/avatar.png and link it's directory as a source. However I'm having trouble finding a way how to save images to to a file using JS. My allowed stack is JS and React, no node.js.
How would I do that? I can have the file as either b64 ot canvas element, so i'm flexible here, as long as it's saved to file.
I'm open to other solutions too.
You can't save a file with client language only. You have to save it to a server, own server or external server or a service like AWS.
The best solution without server-side (strangly) is to use a API for save image and get link from this API. Then you can use this link to Outlook.
You can use https://aws.amazon.com/fr/cloudfront/ free for one year with 50Go and 2 millon request monthly.
If you do not exceed 300,000 images per year you can use this service : https://cloudinary.com/pricing
You can also use https://www.deviantart.com/developers/ but that's not really the point of service.
Weird solution :
Be careful, the login and password of your FTP user will be available in the source of your code. Minimum rights must be administered.
You can use this script for talk to FTP server from JS (not tested but seems worked) : http://www.petertorpey.com/files/ae/scripts/FTPConnection.jsx
You can try something like that :
var ftp = new FtpConnection("ftp://URL") ;
ftp.login("username", "password");
ftp.cd("FOLDER") // For move to folder
ftp.put(file,"FILE.PNG") ; // File must be a File JS Object
ftp.close() ;

An image in the HTML img tag is to be set as the value of file input of HTML while clicking the img tag

<img class='preview' src='preview.png'>
This is an input for image upload:
<input type='file' class='img-upload' accept='image/*'>
When I clicked on the preview image(<img class='preview' src='preview.png'>), I have to change the value of the file input (<input type='file' class='img-upload' accept='image/*'>). The value of the file input should be the preview image.
Short answer: you cannot.
Long answer: The problem is that the file inputs are very sandbox'ed and will not allow user scripts to change their value. The goal is to make sure the user needs to click and acknowledge that he is sending a file from his computer.
Now, the user cannot send the image he clicked on mostly because it is not on his computer (well, technically yes, but even then he would need to know where it is stored and choose it by manually going over the folder). Another thing is, why would you want him to send over a file that you have served him? You could simply get the name of the file or an ID of any sort and use that internally.
Let's take the example of an user avatar. The user gets the possibility to pick between 10 different "preset" pictures, or to upload his own. What you'd do is have 2 form fields, one for the uploaded picture and one for the chosen preset. On server side you would see if the user uploaded a picture, and use that one. If not, use the picture he chose from your server.
I hope I got your question right...
EDIT: If you really, really, really needed to upload the displayed picture, you could get the image data (with ajax I guess), store it into a Blob and send it for upload.
But that has some serious drawbacks. And I think you'll be limited by crossdomain policies so basically you'll only be able to access files that your server can access directly...
Even if you got all that covered, it would be a painfully slow process for the user while all that is required is just sending the name of the picture and the server does the rest.
input type="file" can only be set by the user. Not by a script (not HTML, nor javascript, ...).
Every exe on a windows pc has the capacity to access your files. Including renaming, deleting, encrypting, ... them. For example that's what Wannacry (randsomware) does.
(similar for Mac and Linux, I guess)
A webbrowser is an executable, thus has all those capacities. For security reasons most of these features are turned off, on purpose.
Long ago I wrote a program in C++ (or C#, not sure), with Visual Studio. VS has a webbrowser component. The purpose was to upload multiple albums of photos to a website, but the exe on my pc did have the capacity to use a script to set the input type="file".
So my program could read all subfolders, find all images, automatically upload them, and then the php server saved the albums/images.
In order to stop people like you and me from doing these kind of things, real webbrowsers disabled all these abilities.

Error with downloading image as data url

So, i was doing a link to download an image from a data url(a LARGE one):
<a download='fileName' href="data:image/png;base64,/9j/4WSsRX...">something</a>
However, whenever i try to click in that link i receive an error telling me some net problems.
I have make a fiddle test, but its LARGE(15mb of text) and it will take sometime to load:
https://jsfiddle.net/jjydp1ek/
As the jsfiddle is hard to load, i added a file in mediafire:
http://www.mediafire.com/download/p85y1g442ne9v6m/new++7.html
The test is an image with the same data url value as the link, the image is visible, however i see that the option to open image in a new tab on chrome isn't working.
I do it with canvas in ie 11 and is failing too
Questions:
It is ever possible to make it work with the download link as it is now?
Is there a limit size with the data url to download a file, which is?
How do i do to make the user able to download that image?
Also, ask questions here, or correct any error in the text you see if you think its not understandable.
Thanks.
I have a 70Mb broadband and a powerhouse of a PC and that JS fiddle won't even open.
I don't think it's feasible to have a 15MB encoded string, since that has to be downloaded onto the page each time on every visit. I would try the following:
Optimise the image, you could incorporate gulp-imagemin if you have/want to have Gulp for a build system. I think there are alternatives for Grunt if you wanted to go that way.
Store the file on the server and just place a link to the path, this is the preferred solution.
In response to your questions
The limit:
Length limitations
Although Mozilla supports data URIs of essentially
unlimited length, browsers are not required to support any particular
maximum length of data. For example, the Opera 11 browser limits data
URIs to around 65000 characters.
Source: data URIs - MDN
Downloading
The above suggestion on optimising the image as small as you can get without losing quality if that's a concern. Try it then. If not, it's not a problem to give the user a link to the image / display it on the page. The user can right click and save.
Note
By the time I finished writing this response JSFiddle timed out.

Intermittent failure to load images - ERR_CONTENT_LENGTH_MISMATCH

The problem
My website fails to load random images at random times.
Intermittent failure to load image with the following error in console:
"GET example.com/image.jpg net::ERR_CONTENT_LENGTH_MISMATCH"
Image either doesn't load at all and gives the broken image icon with alt tag, or it loads halfway and the rest is corrupted (e.g. colors all screwed up or half the image will be greyed out).
Setup
Litespeed server, PHP/mySQL website, with HTML, CSS, Javascript, and JQuery.
Important Notes
Problem occurs on all major web browsers - intermittently and with various images.
I am forcing UTF-8 encoding and HTTPS on all pages via htaccess.
Hosting provider states that all permissions are set correctly.
In my access log, when an image fails to load, it gives a '200 OK' response for the image and lists the bytes transferred as '0' (zero).
It is almost always images that fail to load but maybe 5% of the time it will be a CSS file or Javascript file.
Problem occurred immediately after moving servers from Apache to Litespeed and has been persistent over several weeks.
Gzip and caching enabled.
This error is definite mismatch between the data that is advertised in the HTTP Headers and the data transferred over the wire.
It could come from the following:
Server : If a server has a bug with certain modules that changes the content but don't update the content-length in the header or just doesn't work properly.
Proxy : Any proxy between you and your server could be modifying the request and not update the content-length header.
This could also happens if setting wrong content-type.
As far as I know, I haven't see those problem in IIS/apache/tomcat but mostly with custom written code. (Writing image yourself on the response stream)
It could be even caused by your ad blocker.
Try to disable it or adding an exception for the domain from which the images come from.
Suggest accessing the image as a discrete url using cURL, eg
php testCurlimg >image.log 2>&1 to see exactly what is being returned by the server. Then you can move upon level to test the webpage
php testCurlpg >page.log 2>&1 to see the context for mixed data
I just ran into this same ERR_CONTENT_LENGTH_MISMATCH error. I optimized the image and that fixed it. I did the image optimization using ImageOptim but I'm guessing that any image optimization tool would work.
Had this problem today retrieving images from Apache 2.4 when using a proxy I wrote in php to provide a JWT auth gateway for accessing a couchdb backend. The proxy uses php fsockopen and the fread() buffer was set relatively low (30 bytes) because I had seen this value used in other peoples work and I never thought to change it. In all my failing JPG (JFIF) images I found the discrepancy in the original versus the image served was a series of crlf that matched the size of the fread buffer. Increased the byte length for the buffer and the problem no longer exists.
In short, if your fread buffer streaming the image is completely full of carriage returns and line feeds, the data gets truncated. This possibly also relates to the post from Collin Krawll as to why image optimization resolved that problem.

FileAPI doesn't update the files size when user makes file changes (non-webkit browsers)

I figure I'd demonstrate the problem with an example first,
jsfiddle: http://jsfiddle.net/e2UfM/15/
(Tested with FF 12, and Chrome 18.0.1025.168)
Usage:
Load in a text file from your local machine.
Hit "load file".
Hit "display file size" - note the size.
modify & save the text file on your local machine.
Hit "display file size" again. Note how in webkit browsers (Chrome) the file size changes, but in Firefox it didn't update the file size
Non-webkit browsers do not update their size attribute when users make changes to the local file that they have selected whereas Chrome for example does. Both browsers update the contents of the file.
Is there a way to get Firefox to update the file size similar to how Chrome does in this situation?
Simple Real World Example:
User selects a file that's too large for the form, they hit the submit button and get notified that their file is too large (via an alert, "size" bar (see below), etc)
They modify the file locally, and hit submit again.
In Chrome, the file size updates. When the user hits the submit button again, it will validate it's updated size once more and allow the upload. In Firefox, the user must re-select the file on the form before it will see the file size change.
A partial workaround for Firefox - #ZER0's answer
Real world example (in-depth):
One purpose of the File API is to verify file sizes on the client side before uploading to a server if I'm not mistaken.
Consider the scenario where there is a 2MB upload limit in a form and the user chooses a 1MB file. Both Firefox and Chrome will see that the file size is less than 2MB and add it to the form. Let's also say there is a neat bar that shows how big of a file they have chosen, and if it meats the file size limit or not:
But then the user decides to make a minor change to the contents of that file locally before they submit the form and bump the size over 2MB.
In Google Chrome, I can handle this gracefully on the client side. I can check the file size again when the user submits the form, and verify that it is still in fact under 1MB before sending it to the server. But even before the user submits the form, in Chrome, I can go as far as updating the little bar image dynamically as they make changes locally as such:
This "bar" (or any other form on instant notification such as an alert) is useful if the user is filling out a large form. I'd like the user to know instantly when their file is too large and so that they can correct it then, and not just when they submit the form.
In Firefox, because the file size never updates, it will gladly upload the 2MB file thinking that it is still 1MB! I use server side logic to double check the file size, but I'd rather save a server trip.
How I came across the bug:
The above examples are in place to relate to more people as more people have probably dealt with file uploads in forms vs. using the slice function in the File API. This is specifically how I am running into the issue.
In my form, the user selects a file and when they hit submit only the last 10,000 bytes are displayed on the screen in a textarea to confirm that it's really the file that they want.
Consider a file with a size of 50,000 bytes. A user chooses it in the form, and both Chrome and Firefox show bytes 40,000 - 50,000 in the textarea.
Now the user adds some content to the file, and bumps the same file to 70,000 bytes!
Google Chrome will properly update the textarea to contain bytes 60,000-70,000. In Firefox, because the size will remain constant, it will still only show bytes in the range 40,000-50,000.
Edit: Updated the jsfiddle to demonstrate that FF can still read the updated file contents. It's just that the file size does not change with those new contents.
Edit: https://bugzilla.mozilla.org/show_bug.cgi?id=756503 (bug report)
Edit: Examples have been added & updated in response to #Eduárd Moldován's comment & #ZER0's answer. Thanks!
It seems that you're get the size property from the directly, and because the value in this form element is not changed it's likely that Firefox doesn't update the size property as well.
As workaround, you can check the length of the content you have read. So instead of file.size have evt.target.result.length.
However, it's definitely a bug to me so you have done well to add it on Bugzilla!
Update:
You can still use the string version of slice. Otherwise, if you prefer (or the result is a particular type of data), you can create from evt.target.result a new Blob object (The File Object use this interface) where you can use both size property and slice method.

Categories