我已设置 Dropzone,以允许用户使用 PUT 方法将视频直接上传到 S3 预签名 URL。这是我的 Dropzone 脚本:
var presign = "#";
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("#dropzone", {
url: presign,
method: "PUT",
dictDefaultMessage: "Click Here upload video.",
maxFilesize: 10000, // MB
maxFiles: 100,
addRemoveLinks: true,
headers: {
"x-amz-acl": "public-read",
"Content-Type": "video/mp4"
},
init: function() {
this.on("addedfile", function(file) {
fileupload_flag = 1;}
);
this.on("complete", function (file) {
fileupload_flag = 0;
});
this.on("processing", function (file) {
this.options.url = presign;
});
},
accept: function(file, done) {
console.log(file['type']);
if (file && file['type'].split('/')[0] === 'video') {
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.example.com/test-getpresign.php");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("mime="+JSON.stringify(file['type']));
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if(this.status == 200 && this.responseText != '') {
result = JSON.parse(this.responseText);
presign = result.url;
done();
}
}
}
}
else {
done("Please select only supported picture files.");
}
},
success: function(file, response){
this.removeFile(file);
}
});
在实际上传之前触发的“accept”函数中,我运行 xhr 调用我网站上的 PHP 脚本,该脚本为我的 S3 生成预签名 URL,然后将它们返回到 Dropzone 并更新 PUT URL 以指定将文件发送到的位置。用于创建预签名 S3 URL 的 PHP 代码如下:
$cdnvideo = new Aws\S3\S3Client([
'version' => '2006-03-01',
'region' => REGION,
'endpoint' => HOST,
'credentials' => [
'key' => AWS_KEY,
'secret' => AWS_SECRET_KEY,
]
]);
$key = 'video.mp4';
$cmd = $cdnvideo->getCommand('PutObject', [
'Bucket' => 'bucketname',
'Key' => $key,
'ContentType' => 'video/mp4'
]);
$request = $cdnvideo->createPresignedRequest($cmd, '+720 minutes');
$url = (string) $request->getUri();
例如,我尝试上传一个 30 秒、大小为 1.5MB 的视频。看来 Dropzone 向 S3 发送了一些东西。在存储桶列表中,我看到了 S3 上的正确文件名,包括正确的文件大小(1.5 MB)和内容类型“video/mp4”。但是当我在浏览器中转到对象 URL 来查看实际视频时,它是一个时长为 0 秒的视频,HTTP 代码为 206,显然通过网络下载了 1.1MB。视频已损坏,无法加载。
以下是chrome开发者工具中的请求:
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 1570227
Content-Type: video/mp4
Host: *****
Origin: https://www.example.com
Referer: https://www.example.com/
Sec-Ch-Ua: "Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
X-Amz-Acl: public-read
X-Requested-With: XMLHttpRequest
有效载荷:
X-Amz-Content-Sha256: UNSIGNED-PAYLOAD
X-Amz-Algorithm: AWS4-HMAC-SHA256
X-Amz-Credential: A86SB6NKA1KWC4EF8Z25%2F20230821%2Fus-east-1%2Fs3%2Faws4_request
X-Amz-Date: 20230821T015024Z
X-Amz-SignedHeaders: host
X-Amz-Expires: 43200
X-Amz-Signature: 2f00a4eff448fc0ba889ed83e207a87d6df42cd0d7b1252f9a68b1056dec8b09
------WebKitFormBoundaryfApLoQv4mFg4SHAw
Content-Disposition: form-data; name="file"; filename="video.mp4"
Content-Type: video/mp4
------WebKitFormBoundaryfApLoQv4mFg4SHAw--
我没有看到回复,不确定是否应该有。
我在这里做错了什么?这似乎是 Dropzone 的问题。虽然我可能错误地创建了预签名 URL?我的目标是让 Dropzone 将用户的视频放入 S3 并使该对象成为“公开可读”,这样它就可以立即在浏览器中播放。