我正在尝试打开名称中包含拉丁字符的图像 (113_Atlético Madrid
)。
我通过使用 PHP 函数 rawurlencode()
对其名称进行编码来保存它,因此现在它的新名称是 113_Atl%C3%A9tico%20Madrid
。但是当我尝试通过此 URL 打开它时,例如 mysite.com/images/113_Atl%C3%A9tico%20Madrid.png 我收到 404 错误。
如何解决这个问题?
PHP 代码:
if(isset($_FILES['Team'])){
$avatar = $_FILES['Team'];
$model->avatar = "{$id}_".rawurlencode($model->name).".png";
if(!is_file(getcwd()."/images/avatars/competitions/{$model->avatar}")){
move_uploaded_file($avatar['tmp_name']['avatar'], getcwd()."/images/avatars/teams/{$model->avatar}");
}
}
最佳答案
%-encoding 用于 URL。文件名不是 URL。您使用以下表格:
http://example.org/images/113_Atl%C3%A9tico%20Madrid.png
在 URL 中,网络服务器会将其解码为如下文件名:
/var/www/example-site/data/images/113_Atlético Madrid.png
在准备要放入 URL 的文件名时,应该使用 rawurlencode()
,但不应使用它来准备用于光盘存储的文件名。
这里还有一个额外的问题,即在光盘上存储非 ASCII 文件名在跨平台上是不可靠的。特别是如果您在 Windows 服务器上运行,像 move_uploaded_file()
这样的 PHP 文件 API 很可能会使用您不想要的编码,并且最终可能会得到像 113_Atlí 这样的文件名©tico madrid.png
.
对此不一定有简单的解决方法,但您可以使用任何形式的编码,甚至是%编码。因此,如果您坚持使用当前的 rawurlencode()
来创建文件名:
/var/www/example-site/data/images/113_Atl%C3%A9tico%20Madrid.png
这样就可以了,但是您必须使用 double-rawurlencode
来生成匹配的 URL:
http://example.org/images/113_Atl%25C3%25A9tico%2520Madrid.png
但无论如何,将用户可能提供的任意字符串作为文件名的一部分是非常危险的。您可能会受到目录遍历攻击,其中名称包含类似 /../../
的字符串,以访问目标目录之外的文件系统。 (这些攻击通常升级为针对 PHP 应用程序的执行任意代码攻击,这些应用程序通常在较弱的权限下部署。)使用完全合成的名称会更好,如@MatthewBrown 建议的(+1)。
(请注意,这仍然不是允许用户文件上传的安全问题的结束,事实证明这是一个非常难以正确实现的功能。内容嗅探和插件仍然存在问题,可以允许图像文件被重新解释为其他类型的文件,从而导致跨站点脚本问题。为了防止出现这种情况的所有可能性,最好只从单独的主机名提供用户提供的文件,这样针对该主机的 XSS 就不会攻击您针对主站点的 XSS。)
关于php - 图像 URL 中的 unicode 字符 - 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38978495/