Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 强制从s3 amazon服务器下载_Php_Codeigniter_Download_Amazon S3 - Fatal编程技术网

Php 强制从s3 amazon服务器下载

Php 强制从s3 amazon服务器下载,php,codeigniter,download,amazon-s3,Php,Codeigniter,Download,Amazon S3,我一直在开发一个新的web应用程序,它依赖于amazons3服务器作为存储系统,以及codeiginer作为PHP框架 我需要在点击链接时强制下载文件。原始URL如下所示: http://www.our-web.com/download/do/1.jpg 它会生成一个指向Amazon S3服务器上实际文件的临时签名URL,如下所示: http://main_bucket.s3.amazonaws.com/post/1/1.jpg?AWSAccessKeyId=AKIAJEOQKYPKC3CCU5

我一直在开发一个新的web应用程序,它依赖于amazons3服务器作为存储系统,以及codeiginer作为PHP框架

我需要在点击链接时强制下载文件。原始URL如下所示:

http://www.our-web.com/download/do/1.jpg

它会生成一个指向Amazon S3服务器上实际文件的临时签名URL,如下所示:

http://main_bucket.s3.amazonaws.com/post/1/1.jpg?AWSAccessKeyId=AKIAJEOQKYPKC3CCU5RA&Expires=1305395426&Signature=iuzCdA22gImLK192%2BMAhk8OkAY8%3D

我需要让该文件开始下载从真正的亚马逊网址它一旦用户点击链接

我现在有两种方法:

  • 使用
    redirect()
    ,它将打开文件而不是下载文件;或
  • 将标题更改为以下代码:

    header('Content-type: application/force-download');
    header('Content-Disposition: attachment; filename=' . $file_name);
    header('Content-Transfer-Encoding: binary');
    header('Expires: 4000');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($generated_file));
    
    readfile($generated_file);
    
  • 不幸的是,这两种方法都帮不了我。第二种方法是从我的网站下载,而不是直接从亚马逊下载


    如何强制文件直接从Amazon S3服务器下载,而不是从我的网站下载?

    您无法告诉浏览器如何处理远程文件。通过重定向到amazon,你告诉浏览器在那里开始一个新的请求。你无法控制这个请求


    我能想到的唯一解决方案是将图像打包成zip文件或类似文件。当然,这增加了另一种(可能令人讨厌的)复杂性。

    您只需在S3中的文件上设置正确的标题,就可以强制浏览器下载而不是打开文件。设置这些:

    Content-Disposition: attachment; filename=FILENAME.EXT
    Content-Type: application/octet-stream
    
    在将文件上载到S3时,需要设置它们。用你会用的那个


    或者,您可以在S3中使用或通过上传并设置正确的标题后设置这些标题。

    问题是如何通过编程方式进行设置,但要通过AWS控制台手动进行设置:

    • 在S3中选择一个文件
    • 属性>元数据>添加更多元数据
    • 关键字:内容处置值:附件
    • 拯救

    聚会有点晚,但对于一个文件,您通常不想在存储时决定如何使用它。您希望能够将文件存储一次,然后在一个区域中嵌入文件或在浏览器中显示,并在另一个区域中使用户能够下载相同的文件

    幸运的是,您可以通过在请求url中提供覆盖参数来实现这一点。它只适用于已签名的请求,但谢天谢地,您已经这样做了

    如果您添加一个类似于
    &request content type=“application/force download”
    的参数,应该可以实现这一目的

    查看S3获取对象文档的请求参数部分:

    如果您的S3网站位于CloudFront之后,请不要忘记在重试之前使文件无效!这将清除缓存的文件

    您可以通过以下步骤进入失效页面:

    Cloudfront -> Distribution Settings -> Invalidation
    
    然后输入文件的路径


    使该文件无效将需要一些时间。对于我的文件,这需要5分钟。

    使用file\u get\u contents或cURL检索S3文件,然后与Headers进行传递,这就是他使用
    readfile
    所做的。正确,但即使我不希望客户端通过我的网站下载文件。必须有更好的解决方案从另一个域下载。如果您试图利用cloudfront,将文件从您的站点中拉出来是一个糟糕的主意,它可能会将您的内容分发到多达19个边缘节点。图像只是一个示例,也许我忘了提到允许使用多个文件类型,特别是pdf,还有docx。无论如何,谢谢你的回复,但我认为有办法解决这个问题。事实上,很多大型网站都使用外部存储系统。我不知道在将文件上传到S3时设置标题的可能性。很高兴知道。这是可能的,我认为亚马逊还有更好的解决方案可以提供,这就是为什么我们选择亚马逊s3的原因,因为它可以直接从浏览器使用POST直接上传。不管怎样,感谢您的帮助。通过更改文件meta,已经解决了这个问题,代码是:$opt['meta']['Content-Type']='binary/octetstream'@哈立德-太好了。很高兴为您提供帮助:)我相信真正需要的是内容处理标题。不需要设置内容类型。非常有用,因为这个答案在谷歌搜索中排名很高,我需要向非技术人员展示如何在AWS上执行此操作。我相信正确的请求参数是
    请求内容处置=附件;filename=filename.EXT“
    。您的
    请求内容类型
    正在工作,因为它是未知的内容类型,所以浏览器默认情况下会下载它。是的,这就是我想要的。我宁愿不在存储时决定这一点(特别是因为S3中已经有数千个我不想修改的文件).从2019年起,它实际上是卢克评论的
    响应内容处置=附件;%20FILENAME.EXT
    文档