2

好吧,在你对我说之前,这是为了测试目的,是的,我知道这不是一个好主意,但我只是在测试它。(学习新事物)

好的现在一旦录制了视频,它使用 jQuery.post 将其发送到 uploadvideo.php 但我将如何在该页面上检索它?或者我们可以直接将它存储到数据库中吗?从一页而不是发送它?

function postVideoToServer(videoblob) {

    var data = {};
    data.video = videoblob;
    data.metadata = 'test metadata';
    data.action = "upload_video";
    jQuery.post("http://mysite.com/uploadvideo.php", data, onUploadSuccess);
}

在 uploadvideo.php 我有这个

<?php

require("connect.php");

$video = $_POST["video"];
$up = mysql_query("INSERT INTO video VALUES ('$video')");

?>

但这似乎不起作用,任何帮助都会很棒。

4

1 回答 1

1

在将数据插入查询之前,您没有对数据进行转义,因此您遇到了 SQL 注入漏洞。像视频这样的二进制文件往往会非常清楚地说明这一点:它们将包含通常在 SQL 语句中被禁止的字符,而且它们并不为此感到羞耻。

为了解决这个问题,我们将做两件事:

  1. 使用 BLOB(二进制大对象)列类型(如果您还没有这样做)。
  2. 使用准备好的语句(以防止 SQL 注入)。

让我们首先尝试从磁盘插入一个二进制文件。我们将对数据库使用PDO,因为它使准备好的语句变得容易。首先,我们需要做出准备好的声明:

// assuming PDO object in $db
$stmt = $db->prepare("insert into videos values (:video);");

我们没有让 PHP 用 插入我们的变量值$,而是使用:. :在 PHP 中字符串没有任何特殊含义,但对于 SQL,它是一个占位符。现在我们可以告诉 PDO 我们想在其中放入什么值,数据库会得到它并知道它是一个值,而根本不会尝试将其解释为 SQL。您可以以一种相当直接的方式将整数、字符串和其他类型的对象放入其中,但这里有趣的是我们正在处理一个大型二进制文件。与只传入值的其他类型的值不同,PDO 需要一个文件句柄,因此它不必一次将所有数据存储在内存中。让我们打开一个文件并绑定该值:

$file = fopen("video.mp4", "rb");
$stmt->bindValue("video", $video, PDO::PARAM_LOB);  // LOB = Large OBject

现在我们已经填写了所有占位符,我们可以执行语句:

$stmt->execute();

语句执行后,我们可以关闭文件,因为我们不再使用它:

fclose($file);

这就是您将 BLOB 从磁盘插入数据库的方式,但这并没有回答您的问题,您可以从POST请求中获取它。

让我们考虑一个稍微传统一点的例子,没有任何花哨的 AJAX。假设我们有一个普通的旧元素和一个带有 a的form普通旧input元素。文件提交被写入临时文件。然后将文件名存储到. 然后可以将这个临时文件移动到更方便的地方,或者我们可以用它做点什么。typefile$_FILES

由于数据被写入一个临时文件,它仍然是一个文件,我们可以插入它,只是打开一个不同的文件:

$file = fopen($_FILES["video"]["tmp_name"], "rb");

这也很高兴知道,但它仍然不能回答你的问题。真正的方法是什么?

嗯……这很棘手。您的数据来自 JavaScript,其中字符串表示 Unicode 文本,而不是二进制数据。如果您尝试通过网络发送任何超过 127 的代码点,它会以某种方式被编码,不会真正破坏您的数据,而是以一种意想不到的(虽然是可逆的)方式改变它。

较新的浏览器提供Blob, 和Uint8Array对象,使 JavaScript可以处理二进制数据,并且修改XMLHttpRequest和添加FormData它也可以处理二进制数据。

那么在 JavaScript 端要做什么呢?

我假设您想像以前file一样使用标准输入,但让它上传而不刷新页面。当然还有其他方法可以做到这一点,但它们超出了范围。使用您选择的搜索引擎搜索XMLHttpRequest 2.

  1. 获取File. HTML5 将files属性添加到file输入,让您访问当前选定的文件[s]。由于我们可能不处理多文件file输入(另一个 HTML5 补充),我们将只得到第零项:

    var file = document.getElementById('video').files[0];
    
  2. 制作一个FormData并用您的数据填充它。如前所述,FormData这是一个相当新的添加,只有较新的浏览器支持它。但是,对于支持它的浏览器,它使您的生活变得相当轻松:

    var data = new FormData();
    data.append('video', file);
    
  3. 做请求。我们可以XMLHttpRequest以传统方式使用,除了传递sendFormData不是字符串:

    var xhr = new XMLHttpRequest();
    xhr.open("POST", "upload_video.php", true);
    xhr.send(data);
    

您的视频正在上传中!等等,什么?我们在 PHP 端做什么?事实证明,这样做在服务器上的显示方式与在使用没有 AJAX 的普通表单时显示的方式相同。这是正确的; 无需修改。当它像那样工作时很好,对吧?

现在,由于服务器端接口是相同的,我相信您可以让禁用 JavaScript 的人访问它。这并不难;file只需像在第二阶段所做的那样添加一个带有普通元素的普通表单。


我们已经在这里讨论了一些事情,所以只是重申我们使用的主要技术和技巧:

  • 我们使用BLOB列来保存二进制数据。
  • 我们使用PDO与数据库通信并使用准备好的查询。
  • 我们将文件作为大对象参数绑定到准备好的查询。
  • 我们使用上传的文件作为要上传的文件。
  • 我们使用 HTML5 功能和XMLHttpRequest2 接口使用 AJAX 发送二进制数据。
于 2013-06-26T03:48:53.077 回答