使用pre-signed URLs通过浏览器上传

使用presigned URLs,你可以让浏览器直接上传一个文件到S3服务,而不需要暴露S3服务的认证信息给这个用户。下面就是使用minio-js实现的一个示例程序。

服务端代码

  1. constMinio=require('minio')
  2. var client =newMinio.Client({
  3. endPoint:'play.minio.io',
  4. port:9000,
  5. secure:true,
  6. accessKey:'Q3AM3UQ867SPQQA43P2F',
  7. secretKey:'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG'
  8. })

初始化Minio client对象,用于生成presigned upload URL。

  1. // express是一个小巧的Http server封装,不过这对任何HTTP server都管用。
  2. const server =require('express')()
  3. server.get('/presignedUrl',(req, res)=>{
  4. client.presignedPutObject('uploads', req.query.name,(err, url)=>{
  5. if(err)throw err
  6. res.end(url)
  7. })
  8. })
  9. server.get('/',(req, res)=>{
  10. res.sendFile(__dirname +'/index.html');
  11. })
  12. server.listen(8080)

这里是presignedPutObject的文档。

客户端代码

程序使用了jQuery.

用户通过浏览器选择了一个文件进行上传,然后在方法内部从Node.js服务端获得了一个URL。然后通过XMLHttpRequest()往这个URL发请求,直接把文件上传到play.minio.io:9000

  1. <inputtype="file"id="selector"multiple>
  2. <buttononclick="upload()">Upload</button>
  3. <divid="status">No uploads</div>
  4. <scriptsrc="//code.jquery.com/jquery-3.1.0.min.js"></script>
  5. <scripttype="text/javascript">
  6. function upload(){
  7. [$('#selector')[0].files].forEach(fileObj =>{
  8. var file = fileObj[0]
  9. // 从服务器获取一个URL
  10. retrieveNewURL(file, url =>{
  11. // 上传文件到服务器
  12. uploadFile(file, url)
  13. })
  14. })
  15. }
  16. // 发请求到Node.js server获取上传URL。
  17. function retrieveNewURL(file, cb){
  18. $.get(`/presignedUrl?name=${file.name}`,(url)=>{
  19. cb(url)
  20. })
  21. }
  22. // 使用XMLHttpRequest来上传文件到S3。
  23. function uploadFile(file, url){
  24. var xhr =newXMLHttpRequest()
  25. xhr.open('PUT', url,true)
  26. xhr.send(file)
  27. xhr.onload =()=>{
  28. if(xhr.status ==200){
  29. $('#status').text(`Uploaded ${file.name}.`)
  30. }
  31. }
  32. }
  33. </script>

现在你就可以让别人访问网页,并直接上传文件到S3服务,而不需要暴露S3服务的认证信息。

原文: https://docs.minio.io/cn/upload-files-from-browser-using-pre-signed-urls.html