I have a couple of image drop places made with html5. When the image is parsed and converted to data (and encoded in base64), I grab that data and send via post to a php file.
On localhost, that base64 string is received perfectly in the php file. However, when I move to a server, both image preprocessing and base64 sending to the server work (I read the headers), but when in the php file, that base64 string is no longer there. Is there anything I am missing?
Some extra information:
I don't url encode the string, because without doing so it worked locally, and doing that the server still doesn't get the base64 data.
I haven't topped the post_max_size (8M in my case, yet the base64 string plus the other data weights about 50kb)
Breaking news
I tried to upload 600kb of data. Now the server prompts this:
<html><head>
<title>413 Request Entity Too Large</title>
</head><body>
<h1>Request Entity Too Large</h1>
The requested resource<br />/altmail/admin/calls/ajax.previewnewsletter.php<br />
does not allow request data with POST requests, or the amount of data provided in
the request exceeds the capacity limit.
</body></html>
Again, post_max_size is big enough.
Breaking news 2
After uploading the opposite, a 38x38, 220bytes picture, it uploaded correctly.
Check the Apache Request size limits:
http://httpd.apache.org/docs/2.2/mod/core.html#LimitRequestFieldSize
There is a limit in the size of everything where it comes to HTTP, so if something works here and not there, increase the sizes there. ;)
You're saving the base64 data into a file? If so maybe the folder is not marked for "WRITE", check that.
You are using $_POST or is using global variables in Localhost.
If you are using Global change to $_POST.
If you are using RAW, use the variable like this:
$_GLOBALS['HTTP_RAW_POST_DATA']
Related
I've spent good 2 days on this issue and I'm reaching a desperation point. I am hitting my request limits when I am uploading file content via Ajax - Request Entity Too large. I am on an Apache server. I am able to modify php.ini and htaccess but not able to modify any configs beyond this as I do not have access to those.
Problem:
I have a base64 encoded content of an image that I need to upload to my server (roughly 1MB in size). I have tried uploading this value, which results in 413 error code. As an experiment, I've tried uploading an image using a <input type='file' /> field which works for images and files much bigger than 1MB. It seems I am hitting the 413 error only if I have data >1MB present in the request params (eg adding data in an input field, or adding base64 representation of an image into one of the request params). Uploading the same file using File input works fine though.
The real issue is that in my website I can't have users upload image via File Input field. I only have the base64 content of the image that needs to be uploaded. Given that I can't modify my server settings, is there a way I can upload this content into my server??
Additional Info:
I am using JS FormData() object. The content of my form goes into this object and gets uploaded to my server. I can dynamically add values to this object using methods like formdata.append().
If I append large base64 string from above description, I hit a 413 error.
If I add a text field into the form and copy/paste the base64 string into the input field, I also hit the 413 error
If I upload the same image from my machine using <input type='file' /> field and upload the FormData object the image comes through fine.
Hope this is enough info. As a bonus - if anyone can explain why uploading the file via File Input works, but uploading the same data via a text field doesn't that would be quite beneficial also!
For anyone having similar problems in the future, I've found the answer in one of the answers to this question
Essentially we'll add the base64 string as a blob to the formData object using:
var formData = new FormData();
var blob = new Blob(['Lorem ipsum'], { type: 'plain/text' });
formData.append('file', blob,'readme.txt');
This seems to mimic the behaviour of File Input.
I need to send a file in base 64 format through a SOAP service. I cannot save the file locally. Is there a way to convert an uploaded file and send it through in one instance, without saving it?
I initially thought it was as easy as:
$base64file = base64_encode($_FILES["cv"]["tmp_name"]);
But that doesn't seem to be working great.
The problem with your code is that you are encoding the filename, not the file content.
Use this to open the file and convert it to base64:
$base64file = base64_encode(file_get_contents($_FILES["cv"]["tmp_name"]));
Then you can send it back to the client. Just double check that the Soap server does not double base64 encode the string.
I actually want to upload an image to a server.
To achieve this, i want the user just paste the image into chrome (the image is a print screen in fact), and then i post the stream to a php page, convert the stream as an image, and then upload it.
How can i achieve this web application ?
Today i have develop some differents parts :
I used this script, and i create the Upload.php page which gets the post variable and try to Create and image.
The problem i have, is that when i post the data, i only get a blob. I would like to get a base64 stream.
Can you help me ?
Thanks in advance.
I'm not sure why you are specifically looking for a "base 64 stream". If you are sending the Blob to your server via ajax, as far as your server is concerned, it's a file. Treat it no different than any other upload server-side. A Blob is a File without a name property. That's perhaps a bit overly-simplistic, but my point is that, again, this is really nothing more than a file as far as your server knows.
Assuming you are sending a multipart-encoded request, I'd like to point out that most user agents will set the filename property of the item's Content-Disposition header in the request to "blob" when the item you are uploading is a Blob instead of a file. It is possible to change this value in some browsers via the 3rd argument in FormData's append method, but I wouldn't rely on this just yet.
Also note that, if you are interested in a library that handles all of this already, I maintain, Fine Uploader which natively supports uploading images via paste in Chrome.
To answer this old question: Posting an image from clipboard with chrome is pretty much the same as posting a dropped file - except that the image/blob doesn't have the properties "name" and "lastModified".
var entry = items[i].webkitGetAsEntry();
if (!entry) entry = items[i].getAsFile();
if (entry instanceof Blob) /** CHROME pastet Bilder als Blob **/
{
entry.isFile = true;
entry.lastModifiedDate = new Date();
entry.name = ""+new Date().getTime()+"."+entry.type.split('/')[1];
}
if (entry.isFile)
{
//handle dropped file
}
I am using PHP to generate images and this works fine. I am having trouble displaying these images however:
My image generator is a PHP file that takes tons of parameters and loads of data to generate the image. Because of the excessive amounts that has to be passed to the generator, using the GET container does not work for me, so the data is sent via a POST request. The result of this request is the raw image data.
I am using
$result = post_request('http://myurl.com/graphx/generator.php', $data);
if($result['status'] == 'ok') {
echo "<img src=\"data:image/png;base64,".
base64_encode($result['content'])."\"/>\n";
}
to display my image. This works for very small images, but as they get bigger (300px*300px for example), the image is not displayed anymore (it seems to be cut somewhere).
Is my approach reasonable?
Is there any workaround for the size issue?
Update:
When I let the generator save the image to a file, the created file contains the image as I want it to be. Also, if convert my generator into a GET-generator, the following code works properly as well:
$data = http_build_query($data);
echo "<img src=\"http://myurl.com/graphx/get_generator.php?{$data}\"/>\n";
So it definitely seems to be a problem with either the POST request, or the conversion into the base64 format. I'm using the POST request as shown here.
I'd suggest having your page be structured like this:
main page:
<img src="imageproxy.php" />
imageproxy.php:
<?php
$result = post_request('http://myurl.com/graphx/generator.php', $data);
header('Content-type: image/png');
if($result['status'] == 'ok') {
echo $result['content']);
} else {
readfile('error_message_image.png');
}
instead of trying to work with data uris and length limits, just have your proxy script output the actual raw image data and treat it as an image in your client-side html.
According to http://en.wikipedia.org/wiki/Data_URI_scheme IE 8 (and presumably below if they support it) "limits data URIs to a maximum length of 32 KB". This could be what you are seeing if it only reads the first 32k of whatever you are sending it.
Why don't you base64 the parameters and put THAT in the GET request, and do a simple:
<img src="/path/to/php.php?p=eyJ0aGlzIjoiaXMiLCJhIjoiYmVhdXRpZnVsIiwic2V0Ijoib2YiLCJwYXJhbWV0ZXJzIjoiISEifQ==" />
Then on the php.php base64_decode($p) and return the image.
Even better on php.php, use X-Sendfile mod of apache (https://tn123.org/mod_xsendfile/) and perhaps cache the image as well locally so that you don't have to recreate it all the time
Edit:
I don't know exactly how many parameters we are talking about here. If you go and see What is the maximum length of a URL in different browsers? you will see that experience has shown that a URI is pretty much around 2000 characters.
So it depends if your base64 encoded string is less that that you are safe. Otherwise you could think of alternative ways of encoding. Perhaps yEnc or base85?
Even further you could do store a serialized object (containing the parameters needed) on a local storage (ie RDBMS), link it with an id and pass that id around. When php.php get's the id, looks it up on the storage retrieves the parameters creates the image and so on.
I've got a webservice which expects a parameter of type "xs:base64Binary" - this is a file to store in the database.
I'm trying to consume the service using PHP 5's native webservice classes. I've tried a few things:
// Get the posted file
$file = file_get_contents($_FILES['Filedata']['tmp_name']);
// Add the file, encoding it as a base64
$parameters = array("fileBytes" => base64_encode($file));
// Call the webservice
$response = $client->attachFile($parameters);
The result is an error saying "Bad Request." If the file is a text file and I don't base64_encode, it works fine. Problem results when posting a binary file such as an image.
Anyone know the trick here?
EDIT 1
Also problematic is if I encode the text file, it seems to work but of course it's encoded and ends up being junk once downloaded and viewed again (i.e, the text is encoded and doesn't seem to get de-coded by the server).
As far as I know, base64_encode() should be doing the job.
Are you 100% sure $file contains something? Have you made a dump?
Ok, so it seems there is no need to use base64_encode. The file_get_contents already puts it into the required format.
Additionally, the problem was because I had the server side config setting for the maxArrayLength too low.