使用CakePHP和Java Web Start我在控制器中生成必要的.jnlp文件,其中我将文件名设置为标题字段。 这工作正常,只要我不想在文件名中使用特殊的字符。 不过,我希望在主要操作系统上启用每个可能的字符作为文件名。 所以我试图做的是通过replace它们通过空string删除所有无效的字符。 但是,在文件名中应该允许使用空格似乎存在问题。
这是代码:
$panel_id = 1 $panelname = 'whitespace s'; $filename = sprintf('"Project_%d_%s.jnlp"', $panel_id, $panelname); $invalid_chars = array('<', '>', '?', '"', ':', '|', '\\', '/', '*', '&'); $filename = str_replace($invalid_filenamechars, '', $filename); $this->header('Content-Disposition: attachment; filename=' . $filename);
当我这样做时,标题中的结果文件名是'Project_1_w hitespac e',而Windows 7想要将文件保存为'Project_1_w'。 所以,似乎我的操作系统不接受文件名中未转义的空格? 如果不是以下内容,我会很满意这个解释:我留下了第4行和第5行,以便代码看起来像
$panel_id = 1 $panelname = 'whitespace s'; $filename = sprintf('"Project_%d_%s.jnlp"', $panel_id, $panelname); $this->header('Content-Disposition: attachment; filename=' . $filename);
而现在Windows愿意保存文件的所有空格,但我不明白为什么。 如果我使用wireshark查看头文件中的文件名,两者是相同的。 如果sprintf行被replace为$filename = 'whitespac e'
或者甚至$filename = $panelname
它会像在第一个codesnippet中一样切割文件名。 但是我可以使用dottet-string-concat语法replacesprintf,它可以工作。
谁能告诉我,我忽略了什么?
不同的是双引号。 随着第一个代码,你会最终:
Content-Disposition: attachment; filename=Project_1_w hitespace s.jnlp
与第二个代码,你会最终:
Content-Disposition: attachment; filename="Project_1_w hitespace s.jnlp"
你可能想要的是这样的:
$panel_id = 1; $panelname = 'whitespace s'; $filename = sprintf('"Project_%d_%s.jnlp"', $panel_id, $panelname); $invalid_chars = array('<', '>', '?', '"', ':', '|', '\\', '/', '*', '&'); $filename = str_replace($invalid_filenamechars, '', $filename); $this->header('Content-Disposition: attachment; filename="'.$filename.'"');
这将去除$ filename中的任何双引号,但是确保$ filename始终被双引号括起来。
RFC 2616是HTTP / 1.1规范,它说:
如果用户请求将内容保存到文件中,Content-Disposition响应头字段已被提议作为原始服务器建议默认文件名的手段。 此用法源自RFC 1806中的Content-Disposition的定义。
content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) disposition-type = "attachment" | disp-extension-token disposition-parm = filename-parm | disp-extension-parm filename-parm = "filename" "=" quoted-string disp-extension-token = token disp-extension-parm = token "=" ( token | quoted-string )
一个例子是Content-Disposition:附件; 文件名= “fname.ext”
因此,发送这个:
header('Content-Disposition: attachment; filename="' . $filename . '"');
符合第二种形式( quoted-string
),并应该做你期望的 – 注意只发送SPACE
(ASCII dec 32 / hex 20)作为空白,而不是一些其他奇特的空白字符。