iCo*_*ers 5 php amazon-s3 laravel laravel-4 laravel-5.2
我正在使用亚马逊s3,但在这里我遇到了两个问题
1.当我提交表格时,我无法直接将文件上传到亚马逊服务器.我的意思是我必须上传图片到上传文件夹,从那里我必须检索并上传到.s3 server有没有办法在我们点击提交时直接上传图片?
2.如果我通过'public'在s3 put object那么只有我才能访问或查看文件,但如果我把它公开每个人都可以查看文件,但我需要的所有文件和查看保护只对通过认证的用户.可以任何一个建议我如何解决这个问题?
try {
$s3 = \Storage::disk('s3');
$s3->put($strFileName, file_get_contents($img_path.$strFileName), 'public');
} catch (Aws\Exception\S3Exception $e) {
echo "There was an error uploading the file.\n"+$e;
}
Run Code Online (Sandbox Code Playgroud)
在提问之前我已经从stackoverflow读了这么多答案,但它没有帮我修复我的问题.谢谢
小智 5
对于你的第一个问题,可以直接将图像上传到AWS S3。
$s3 = \Storage::disk('s3')->getDriver();
$s3->put($filePath, file_get_contents($file), array('ContentDisposition' => 'attachment; filename=' . $file_name . '', 'ACL' => 'public-read'));
Run Code Online (Sandbox Code Playgroud)
您应该指定您的文件路径和从表单中获取的文件。
我最近解决了这个问题。首先,是的,您可以直接上传到 s3,这是我用于获取有关此内容的一些信息的内容:http://docs.aws.amazon.com/AmazonS3/latest/dev/HTTPPOSTExamples.html
首先,您需要创建一个策略和签名服务器端以添加到您的 html 表单中以上传文件。
$policy = base64_encode(json_encode([
"expiration" => "2100-01-01T00:00:00Z",
"conditions" => [
["bucket"=> "bucketname"],
["starts-with", '$key', "foldername"],
["acl" => "public-read"],
["starts-with", '$Content-Type', "image/"],
["success_action_status" => '201'],
]
]));
$signature = base64_encode(hash_hmac('sha1',$policy,getenv('S3_SECRET_KEY'),true));
Run Code Online (Sandbox Code Playgroud)
现在,在前端我的表单上,我不使用提交按钮,您可以使用提交按钮,但您需要捕获提交并防止表单实际提交,直到上传完成。
当我们点击保存时,它会生成一个md5(使用npm安装)文件名,这样文件名就不能真正被随机猜测,然后它使用ajax将文件上传到S3。完成后,它将文件数据和返回的 aws 数据放入隐藏输入中并提交表单。它应该看起来像这样:
<form action="/post/url" method="POST" id="form">
<input type="text" name="other_field" />
<input type="file" class="form-control" id="image_uploader" name="file" accept="image/*" />
<input type="hidden" id="hidden_medias" name="medias" value="[]" />
</form>
<input type="button" value="save" id="save" />
<script>
$(document).ready(function(){
$('#save').click(function(){
uploadImage(function () {
$('#form').submit();
});
});
});
var uploadImage = function(callback) {
var file = $('#image_uploader')[0].files[0];
if(file !== undefined) {
var data = new FormData();
var filename = md5(file.name + Math.floor(Date.now() / 1000));
var filenamePieces = file.name.split('.');
var extension = filenamePieces[filenamePieces.length - 1];
data.append('acl',"public-read");
data.append('policy',"{!! $policy !!}");
data.append('signature',"{!! $signature !!}");
data.append('Content-type',"image/");
data.append('success_action_status',"201");
data.append('AWSAccessKeyId',"{!! getenv('S3_KEY_ID') !!}");
data.append('key',filename + '.' + extension);
data.append('file', file);
var fileData = {
type: file.type,
name: file.name,
size: file.size
};
$.ajax({
url: 'https://{bucket_name}.s3.amazonaws.com/',
type: 'POST',
data: data,
processData: false,
contentType: false,
success: function (awsData) {
var xmlData = new XMLSerializer().serializeToString(awsData);
var currentImages = JSON.parse($('#hidden_medias').val());
currentImages.push({
awsData: xmlData,
fileData: fileData
});
$('#hidden_medias').val(JSON.stringify(currentImages));
callback();
},
error: function (errorData) {
console.log(errorData);
}
});
}
};
</script>
Run Code Online (Sandbox Code Playgroud)
然后,监听提交的控制器解析该输入字段中的 JSON,并创建一个 Media 实例(我创建的模型),并存储每个图像的awsData和。fileData
然后,不要将 html 图像标签指向 s3 文件,如下所示:
<img src="https://{bucketname}.s3.amazonaws.com/filename.jpg" />
Run Code Online (Sandbox Code Playgroud)
我做了这样的事情:
<img src="/medias/{id}" />
Run Code Online (Sandbox Code Playgroud)
然后该路由可以通过普通的auth中间件以及您在 Laravel 中需要做的所有事情。最后,该路由指向执行此操作的控制器:
public function getResponse($id)
{
$media = Media::find($id);
return (new Response('',301,['Location' => $media->info['aws']['Location']]));
}
Run Code Online (Sandbox Code Playgroud)
因此,它所做的只是使用 301 重定向并将标头位置设置为实际的 aws 文件。由于我们在将文件上传到 aws 时会生成 md5 文件名,因此每个文件名都是 md5,因此人们无法随机搜索存储桶中的 aws 文件。
| 归档时间: |
|
| 查看次数: |
3670 次 |
| 最近记录: |