无法将大型 html5 画布发布到服务器?

发布于 2024-10-18 01:59:06 字数 940 浏览 1 评论 0原文

我有一块画布,你可以在上面作画。我需要将其内容保存到服务器,以便稍后可以恢复。

为此,我通过 xMLHttpReq.open("POST", url, false);

在我的 php 脚本中,我获取 $_POST 和 base64_decode(json_decode($_POST[data])) 并将其保存到服务器上的 .png 文件中。

现在,如果画布上有一个小涂鸦,效果就很好。但是,如果 1600x1200px 画布上绘制了很多内容,并且大小约为 600kB,则我的脚本会失败,并且我会在服务器上得到一个 0kB png。

我该如何解决这个问题?如何将大画布发送到服务器?

问题是否是 _POST 大小的限制?因为,无论画布有多大,我总是可以通过 window.open(canvasP.toDataURL(), "blabla"); 下载它。

这对我来说是一个两难的境地。任何帮助将不胜感激!

[编辑] PHP 只是接收空的 $_POST[data] 对于任何超过 ~50 kB 的内容... 因此,问题必须发生在 canvasP.toDataURL() 和 POST-ing...

[EDIT2] 浏览器显示“正在上传...(xx%)”,直到“完成”为止。那么数据去哪儿了? :C

[EDIT3] 这是应用程序,请亲自尝试一下(使用谷歌浏览器): http: //students.info.uaic.ro/~tudor.berechet/

[EDIT4] Mike关于suhosin的回答似乎是正确的 “phpinfo截图”

I have a canvas that you can paint on. I need to save it's contents to the server so it can be resumed later.

To do this, I xMLHttpReq.send(*) the encodeURIComponent(canvasP.toDataURL())* via a xMLHttpReq.open("POST", url, false);

In my php script, I take the $_POST and base64_decode(json_decode($_POST[data])) and I save it to a .png file on the server.

NOW, this works fine and dandy if the canvas has a small doodle on it. BUT if the 1600x1200px canvas has a lot of stuff drawn on it, and it's like 600kB in size, my script fails, and I get a 0kB png on my server.

How do I fix this? How can I send a large canvas to the server?

Is the problem a limitation to _POST size? Because, no matter how large the canvas is, I can always download it via a window.open(canvasP.toDataURL(), "blabla");.

This is quite the dilemma for me. Any help will be much appreciated!

[EDIT] The PHP simply receives empty $_POST[data] for anything over ~50-something kB...
So the problem has to occur between canvasP.toDataURL() and the POST-ing...

[EDIT2] Browser says "Uploading...(xx%)" until it's "done". SO WHERE DOES THE DATA GO? :C

[EDIT3] Here's the app, try it for yourself (use google chrome): http://students.info.uaic.ro/~tudor.berechet/

[EDIT4] Mike's answer seems to be right about suhosin phpinfo screenshot

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

っ左 2024-10-25 01:59:06

听起来很像你的 php 是用 Suhosin 编译的。 Suhosin 的任何 post 变量的默认限制长度是 65000 字节,这是相当大的接近您估计的极限。

事实上,您的服务器正在发送值为 PHP/5.2.6-1+lenny9X-Powered-By 标头。我用 google 搜索了这个软件包版本,在 Debian 网站上他们提到它是用 Suhosin 构建的

由于您无法控制服务器配置,因此解决方案是将画布数据拆分为低于服务器帖子长度限制的多个变量,然后在 PHP 中重新组装。如果您检查您的 phpinfo() 它应该显示所有这些限制。

编辑 - 添加示例代码

Javascript:

var canvasData = canvasP.toDataURL(); 
var length = canvasData.length;
var content = '';
var index = 0;
var limit = 64999;
var l;
while (length > 0) {
    if (length <= limit)
        l = length;
    else
        l = limit;

    content += '&content[]=' + canvasData.substr(index * limit, l);
    length -= l;
    index++;
}

xhr.send(content);

我不相信您需要您拥有的encodeURIComponent(),因为toDataURL() 编码为 url 安全的 base64。

PHP:

if (!empty($_POST['content']) && is_array($_POST['content']))
{
    $content = '';
    foreach ($_POST['content'] as $part)
    {
        $content .= $part;
    }
    $content = base64_decode($content);
}

不是最有效的方法,但它可能对您有帮助。

Suhosin 仍然有其限制,但您将能够通过这种方式发送更多数据。看起来您将被限制为数组中 65000 字节的 64 个部分,然后您还必须使用多个数组。然而,到那时,对于大多数人来说,它已经变得太大而无法经常上传,并且最好以某种方式发送对图像的更改而不是整个图像。

It sounds very much like your php was compiled with Suhosin. The default limit of length for any post variable with Suhosin is 65000 bytes which is quite close to what you are estimating as your limit.

In fact, your server is sending the X-Powered-By header with a value of PHP/5.2.6-1+lenny9. I googled this package version and on the Debian website they mention it was built with Suhosin.

Since you do not have control over your server configuration, the solution would be to split up the canvas data into multiple variables below the post length limit of your server and then reassemble in PHP. If you check your phpinfo() it should show all these limits.

Edit - Added example code

Javascript:

var canvasData = canvasP.toDataURL(); 
var length = canvasData.length;
var content = '';
var index = 0;
var limit = 64999;
var l;
while (length > 0) {
    if (length <= limit)
        l = length;
    else
        l = limit;

    content += '&content[]=' + canvasData.substr(index * limit, l);
    length -= l;
    index++;
}

xhr.send(content);

I don't believe you need the encodeURIComponent() you have because toDataURL() encodes as base64 which is url safe.

PHP:

if (!empty($_POST['content']) && is_array($_POST['content']))
{
    $content = '';
    foreach ($_POST['content'] as $part)
    {
        $content .= $part;
    }
    $content = base64_decode($content);
}

Not the most efficient method to do this, but it may help you.

This will still have it's limits with Suhosin, but you will be able to send much more data this way. Looks like you will be limited to 64 parts of 65000 bytes in an array before you will also have to use multiple arrays. However, at that point it will already getting way too large for most people to be uploading often and it would probably be better to send the changes to the image somehow instead of the whole image.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文