使用静态处理程序服务时是否可以更改下载文件名?
Is it possible to change the download filename when serving with static handler?
在 cowboy2 中使用静态文件处理程序提供文件时,"download" 文件名是否可能与磁盘上的实际文件名不同?
例如,假设我正在提供静态文件“123”。当用户在浏览器中下载它时,是否可以将其显示为“123.txt”?
因为现在,我的所有文件名都会自动分配一个扩展名为“.dms”的文件名。
我不认为静态处理程序的正常操作是 return 您的浏览器下载的文件。
When the static handler fails to [recognize] the extension, it will
send the file as application/octet-stream. A browser receiving such
file will attempt to download it directly to disk.
稍微备份一下,http 响应几乎总是包含 Content-Type
header,它指定发送到浏览器的内容类型,以便浏览器知道如何显示内容.内容的类型用 mime type
指定。包含典型 html 页面的响应具有如下所示的 Content-Type header:
Content-Type: text/html; charset=utf-8
text/html
mime 类型告诉浏览器不要将文件显示为文本,而是 将 文本显示为 html。
Cowboy 查看请求文件的扩展名以确定在响应的 Content-Type header 中指定的 MIME 类型。如果文件没有扩展名,Cowboy 会将 mime 类型指定为 application/octet-stream
,这会导致您的浏览器下载该文件。你的浏览器基本上说,"I have no idea how to display this binary data, so here, you take the file and figure out what to do with it."
如果所有没有扩展名的文件都是(纯)文本文件,那么您可以告诉牛仔为所有匹配路径的文件设置 text/plain
的 mime 类型:
hello_erlang/src/hello_erlang_app.erl:
-module(hello_erlang_app).
-behaviour(application).
-export([start/2]).
-export([stop/1]).
start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/dog/[...]", cowboy_static,
{
priv_dir,
hello_erlang,
"static/assets",
[{mimetypes, {<<"text">>, <<"plain">>, []} }] %<**HERE
}
},
{"/please_upgrade_to_websocket", myws_handler, []}
]}
]),
{ok, _} = cowboy:start_clear(my_http_listener,
[{port, 8080}],
#{env => #{dispatch => Dispatch} }
),
hello_erlang_sup:start_link().
stop(_State) ->
ok.
Mime 类型使用语法 word1/word2
,而 cowboy 采用您在此处指定的语法:
[{mimetypes, {<<"text">>, <<"plain">>, []} }]
并用正斜杠将两个单词连接起来以生成 mime 类型的 "text/plain"。
目录结构:
hello_erlang/priv/static/assets/
file1
file2
file3
url:
http://localhost:8080/dog/file1
您还可以让 cowboy 调用自定义函数来设置文件的 mime 类型:
hello_erlang/src/hello_erlang_app.erl:
-module(hello_erlang_app).
-behaviour(application).
-export([start/2]).
-export([stop/1]).
start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/dog/[...]", cowboy_static,
{
priv_dir,
hello_erlang,
"static/assets",
[{mimetypes, my_mime_setter, set_type}] %<** HERE {mimetypes, MODULE, FUNCTION}
}
},
{"/please_upgrade_to_websocket", myws_handler, []}
]}
]),
{ok, _} = cowboy:start_clear(my_http_listener,
[{port, 8080}],
#{env => #{dispatch => Dispatch} }
),
hello_erlang_sup:start_link().
stop(_State) ->
ok.
hello_erlang/src/my_mime_setter.erl:
-module(my_mime_setter).
-export([set_type/1]).
set_type(Path) ->
Fname = filename:basename(Path),
TextFiles = [<<"file1">>, <<"file2">>],
case filename:extension(Fname) of
<<>> -> %no extension found(Yeah, I thought this would be an empty list, too!)
case lists:member(Fname, TextFiles) of
true -> {<<"text">>, <<"plain">>, []};
false -> {<<"text">>, <<"html">>, []}
end;
Ext ->
case Ext of
<<".html">> -> {<<"text">>, <<"html">>, []};
<<".css">> -> {<<"text">>, <<"css">>, []};
<<".js">> -> {<<"application">>, <<"javascript">>, []};
_Other -> {<<"application">>, <<"octet-stream">>, []}
end
end.
您可以使用这些文件测试自定义 MIME setter:
hello_erlang/priv/static/assets/file1:
<div><font color="red">red text</font></div>
hello_erlang/priv/static/assets/file4:
<div><font color="red">red text</font></div>
如果您请求第一个文件:
http://localhost:8080/dog/file1
mime 类型将设置为 text/plain
,并且浏览器不会呈现 html,而是您会看到原始的 html。如果请求第二个文件:
http://localhost:8080/dog/file4
mime 类型将设置为 text/html
,这将导致浏览器呈现文本,您应该会看到一些红色文本。
如果你想对有扩展名的文件下注,你可以写:
_Ext ->
cow_mimetypes:web(Fname)
cowboy 将使用其算法得出 mime 类型。
在 cowboy2 中使用静态文件处理程序提供文件时,"download" 文件名是否可能与磁盘上的实际文件名不同?
例如,假设我正在提供静态文件“123”。当用户在浏览器中下载它时,是否可以将其显示为“123.txt”?
因为现在,我的所有文件名都会自动分配一个扩展名为“.dms”的文件名。
我不认为静态处理程序的正常操作是 return 您的浏览器下载的文件。
When the static handler fails to [recognize] the extension, it will send the file as application/octet-stream. A browser receiving such file will attempt to download it directly to disk.
稍微备份一下,http 响应几乎总是包含 Content-Type
header,它指定发送到浏览器的内容类型,以便浏览器知道如何显示内容.内容的类型用 mime type
指定。包含典型 html 页面的响应具有如下所示的 Content-Type header:
Content-Type: text/html; charset=utf-8
text/html
mime 类型告诉浏览器不要将文件显示为文本,而是 将 文本显示为 html。
Cowboy 查看请求文件的扩展名以确定在响应的 Content-Type header 中指定的 MIME 类型。如果文件没有扩展名,Cowboy 会将 mime 类型指定为 application/octet-stream
,这会导致您的浏览器下载该文件。你的浏览器基本上说,"I have no idea how to display this binary data, so here, you take the file and figure out what to do with it."
如果所有没有扩展名的文件都是(纯)文本文件,那么您可以告诉牛仔为所有匹配路径的文件设置 text/plain
的 mime 类型:
hello_erlang/src/hello_erlang_app.erl:
-module(hello_erlang_app).
-behaviour(application).
-export([start/2]).
-export([stop/1]).
start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/dog/[...]", cowboy_static,
{
priv_dir,
hello_erlang,
"static/assets",
[{mimetypes, {<<"text">>, <<"plain">>, []} }] %<**HERE
}
},
{"/please_upgrade_to_websocket", myws_handler, []}
]}
]),
{ok, _} = cowboy:start_clear(my_http_listener,
[{port, 8080}],
#{env => #{dispatch => Dispatch} }
),
hello_erlang_sup:start_link().
stop(_State) ->
ok.
Mime 类型使用语法 word1/word2
,而 cowboy 采用您在此处指定的语法:
[{mimetypes, {<<"text">>, <<"plain">>, []} }]
并用正斜杠将两个单词连接起来以生成 mime 类型的 "text/plain"。
目录结构:
hello_erlang/priv/static/assets/
file1
file2
file3
url:
http://localhost:8080/dog/file1
您还可以让 cowboy 调用自定义函数来设置文件的 mime 类型:
hello_erlang/src/hello_erlang_app.erl:
-module(hello_erlang_app).
-behaviour(application).
-export([start/2]).
-export([stop/1]).
start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/dog/[...]", cowboy_static,
{
priv_dir,
hello_erlang,
"static/assets",
[{mimetypes, my_mime_setter, set_type}] %<** HERE {mimetypes, MODULE, FUNCTION}
}
},
{"/please_upgrade_to_websocket", myws_handler, []}
]}
]),
{ok, _} = cowboy:start_clear(my_http_listener,
[{port, 8080}],
#{env => #{dispatch => Dispatch} }
),
hello_erlang_sup:start_link().
stop(_State) ->
ok.
hello_erlang/src/my_mime_setter.erl:
-module(my_mime_setter).
-export([set_type/1]).
set_type(Path) ->
Fname = filename:basename(Path),
TextFiles = [<<"file1">>, <<"file2">>],
case filename:extension(Fname) of
<<>> -> %no extension found(Yeah, I thought this would be an empty list, too!)
case lists:member(Fname, TextFiles) of
true -> {<<"text">>, <<"plain">>, []};
false -> {<<"text">>, <<"html">>, []}
end;
Ext ->
case Ext of
<<".html">> -> {<<"text">>, <<"html">>, []};
<<".css">> -> {<<"text">>, <<"css">>, []};
<<".js">> -> {<<"application">>, <<"javascript">>, []};
_Other -> {<<"application">>, <<"octet-stream">>, []}
end
end.
您可以使用这些文件测试自定义 MIME setter:
hello_erlang/priv/static/assets/file1:
<div><font color="red">red text</font></div>
hello_erlang/priv/static/assets/file4:
<div><font color="red">red text</font></div>
如果您请求第一个文件:
http://localhost:8080/dog/file1
mime 类型将设置为 text/plain
,并且浏览器不会呈现 html,而是您会看到原始的 html。如果请求第二个文件:
http://localhost:8080/dog/file4
mime 类型将设置为 text/html
,这将导致浏览器呈现文本,您应该会看到一些红色文本。
如果你想对有扩展名的文件下注,你可以写:
_Ext ->
cow_mimetypes:web(Fname)
cowboy 将使用其算法得出 mime 类型。