当前位置: 首页 > 知识库问答 >
问题:

Apache使用特殊字符重写我的编码文件名

壤驷宏才
2023-03-14

我有一个问题,下载文件有特殊字符在它像"ñ"或"的"。

我正在对每个文件名应用rawurlencode()。但是当我走上这条路线时,apache正在重写我的url。

<td>
  <a href="{{asset("storage/" . rawurlencode($fyi->file))}}" target="_blank">{{$fyi->name}}</a></td>

当我检查a标签中的href时,我得到了正确的URL编码路由,如下图所示。

带有编码url的标记

但是当我点击链接时,编码的数据丢失了

点击链接后丢失编码

这里是我的apache配置

<VirtualHost *:80>
    ServerName xxx.com
    ServerAlias xxx.con

    DocumentRoot /home/dev/xxx.com/public
    AllowEncodedSlashes On


    <Directory /home/dev/xxx.com/public>
        Options +Indexes +FollowSymLinks +MultiViews
        AllowOverride All
    Order allow,deny
    allow from all
    Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/xxx.com-error.log
    CustomLog ${APACHE_LOG_DIR}/xxx.com-access.log combined
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =xxx.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [QSA,L]
</VirtualHost>

共有1个答案

严远
2023-03-14

它只是一个浏览器,可以很好地向您显示它。检查浏览器devtools或服务器日志中的“网络”选项卡,您将看到它实际上已编码。

真正的问题是另一个问题——Unicode规范化。这是一个复杂的话题,请看这个和这个答案的解释。

我们可以看到,这是您问题的解决方案,因为虽然您的原始链接不起作用,但此链接起作用。我用替换了,这两个字符是两个字符,一个N后跟一个“组合瓷砖”(1个字符)与(2个字符)看起来相同,但编码不同!

tl;dr:用Unicode表示同一事物有几种方法。您将获得一个链接,该链接将作为单个字符U 00D1:带波浪号的拉丁文大写字母N,但您的实际文件似乎将作为两个字符:U 004E:拉丁文大写字母N后跟U 0303:组合波浪号

为了确保它工作,最好确保“规范化”表示在任何地方都使用,即形式“NFC”(还有“NFD”,即您当前的文件名)。请注意,Mac倾向于使用NFD,而其他*NIX通常使用NFC,如果您从Mac上传文件时没有转换文件名,则这可能是一个问题。

解决方法是在存储文件夹上运行congmv工具来转换所有文件的文件名:

convmv -r -i -f utf8 -t utf8 --nfc --notest .

或者(或者另外),你可以试着理解不正确的链接从哪里来,但是在Linux上有NFD文件名无论如何都是错误的根源,因为你永远不知道是哪个库或客户端或者其他什么东西会犯这个错误在某个时候意外地规范化文件名——几年后当你添加一些新功能时,它可能会作为一个错误回来,所以最好首先确保文件名使用NFC。

你可以考虑的另一个选项是在数据库中有一个文件元数据索引,而不是用它的实际文件名来存储文件(顺便说一下,这也可能导致安全漏洞),但是以一些随机ID作为名称,然后通过其ID对其进行识别,并在下载时在内容处置标题中返回原始名称,以便用户在最后获得正确的文件名。为了改善用户体验,您可以创建像/storage这样的URL/

 类似资料:
  • 相关网站:http://nubix.ca/blog/we-have-a-drone-and-were-prepared-to-shot/

  • 我有一个带有一些特殊字符的mysql数据库,一个输入表单,一些PHP页面。 > 这个页面发送(通过GET)一个参数到另一个php页面(ResultsPage)。 最后这个php页面(ResultsPage)向dbms发送一个带有参数的查询并显示结果。 RequestPage编码为utf-8至 meta http equiv=“Content Type”Content=“text/html;char

  • 问题内容: 我打开 记事本 (Windows)并编写 并转到“ 另存为… ”“ someFile.txt”,并将“ 编码” 设置为 UTF-8 。 在Java中,我有 但是我得到问号和类似的“特殊”字符。为什么? 编辑: 我有此输入(.txt文件中的一行) 和这段代码 和 吐司 输出(用于那些谁不熟悉与Android,吐司只是一个显示弹出式屏幕,在它特定的文本法)的罚款。控制台显示“奇怪的字符”(

  • 出于测试的目的:当它解析数据时,我将一些数据输出到一个呈现完美的浏览器。。 然后我试着用php将它写到一个文件中,如下所示- 和 和

  • 问题内容: 我试图编写一个文件名带有特殊字符的文件,例如“téééê.mp3”,但文件名始终保留“?” 我尝试了几种方法来代替字符“é”,但没有找到解决方法: 我也尝试过这种方式。 问题答案: 尝试: 现在,如果这是您的文件系统不支持此类文件名的问题,您将得到一个;。不同于,新的API拒绝创建可能最终无法读取的文件名。 如果确实无法创建路径,那么,您将必须找到某种逃避和撤消逃避的方法。也许写一个别

  • 问题内容: 我得到了一个像这样的字符串 我该如何编写Java代码来解码编码字符,例如 在字符串中。是否有任何现有的类/方法可以对其进行解码? 谢谢。 问题答案: 要取消转义HTML / XML实体,请使用Apache Commons Lang 或homegrow one 。