【问题标题】:Can't POST large html5 canvas to server?无法将大型 html5 画布发布到服务器?
【发布时间】:2011-06-30 19:55:17
【问题描述】:

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

为此,我通过xMLHttpReq.open("POST", url, false);xMLHttpReq.send(*)encodeURIComponent(canvasP.toDataURL())*

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

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

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

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

这对我来说是个难题。任何帮助将不胜感激!

[编辑] PHP 只接收空的$_POST[data] 任何超过〜50-something kB... 所以问题必须发生在canvasP.toDataURL()和POST-ing之间......

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

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

[EDIT4] Mike 对 suhosin 987654322@的回答似乎是正确的

【问题讨论】:

  • 在 PHP 端失败的消息是什么?听起来像是脚本中的内存问题...
  • 您服务器的post_max_size 是什么?发送到服务器的 URI 编码数据的实际大小是多少?
  • 我不知道如何检查服务器端的任何内容,因为我不拥有服务器并且除了 FTP 访问之外我无法控制它。 Sdleihssirhc,所以您是说服务器说明_Post 消息可以多长时间?我下载了 2 张图片,495kB 和 632kB,但在服务器上失败了。
  • 您可能无法修改首选项,但您始终可以从 php 中读取它们:ini_get('post_max_size')
  • 您需要尝试从 PHP 脚本中获得响应。一定会有一个响应体在某个地方。我敢打赌它包含 PHP 错误。

标签: php javascript html canvas http-post


【解决方案1】:

听起来很像你的 php 是用Suhosin 编译的。使用 Suhosin 的任何 post 变量的 default limit 长度为 65000 字节,非常接近您估计的极限。

实际上,您的服务器正在发送值为PHP/5.2.6-1+lenny9X-Powered-By 标头。我用谷歌搜索了这个软件包版本,在 Debian 网站上他们提到它是built with 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() 编码为 base64,这是 url 安全的。

PHP:

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

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

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

【讨论】:

  • 感谢您的了解。我自己对服务器端的东西不是很有经验。所以现在我必须将字符串分成
  • 有趣...没想到,php构建可能有限制。
  • 我不确定除了 POST 之外还有什么更简单的方法可以发送数据,但您不一定要进行多次 POST。您只需使用单个 POST 发送多个变量,每个变量都小于 65000 字节。只要所有值的总和低于post_max_size 的限制,就可以了。我已经更新了您可以用来执行此操作的可能方法的答案,但是它未经测试,所以我不确定它是否会起作用。当然,如果您可以在没有安装 Suhosin 的情况下获得一些主机,那会好很多,但这并不总是可行的。
  • 现在我明白了!我原以为 suhosin 会覆盖 post_max_size 的 12M 限制。也非常感谢示例代码。我现在肯定会让它工作。我使用的是encodeURIComponent(),因为除了画布内容之外,我还在发送的数据中附加了一个不同的变量,其中包含一个 URL...
  • @Myself Edit 众所周知,encodeURIComponent(your_base64) 似乎是必需的。如果没有 URI 编码,它就不起作用。换句话说,base64 似乎不是 _POST 安全的。
猜你喜欢
  • 2015-05-03
  • 2013-12-06
  • 2012-02-16
  • 1970-01-01
  • 2018-11-10
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
  • 1970-01-01
相关资源
最近更新 更多