为什么某些无效的 MIME 类型会触发 "TypeError," 而其他无效的 MIME 类型会绕过错误并触发自动下载?
Why do some invalid MIME types trigger a "TypeError," and other invalid MIME types bypass the error and trigger an unprompted download?
我正在制作一个相当简单的 Express 应用程序,只有几条路线。我的问题不是关于应用程序的功能,而是关于 Express 路线的一些奇怪行为。
当我启动服务器并使用 /search/*
路由或任何接受参数的路由时,我将这四种内容类型之一应用于响应:
res.setHeader('content-type', 'plain/text');
res.setHeader('content-type', 'plain/html');
res.setHeader('content-type', 'html/plain');
res.setHeader('content-type', 'html/text');
参数作为文件下载,没有任何提示。因此,使用 search/foobar
会下载一个名为 "foobar" 的文件,其大小为 6 字节且文件类型不受支持。现在我明白这四种类型中的 none 是实际的 MIME 类型,我应该使用 text/plain
或 text/html
,但为什么要下载?这两种 MIME 类型的行为与它们应该的一样,并且以下具有类型但没有子类型的 MIME 类型都像它们应该的那样失败,它们都是 return 错误 TypeError: invalid media type
:
res.setHeader('content-type', 'text');
res.setHeader('content-type', 'plain');
res.setHeader('content-type', 'html');
为什么某些无效类型会触发错误,而其他无效类型会绕过错误并触发下载?
到目前为止我发现了什么:
我在 Express 4.x 文档中发现 res.download(path [, filename])
将路径中的文件作为“附件”传输,并且通常会提示用户下载,但这种下载既不是提示也不是故意的.
我无法在 Express 文档(或此处的 SO)中找到任何类似的情况,其中 运行 路由导致文件自动下载到您的计算机。
起初我以为 res.send(typeof(res));
行导致了下载,但是在一次注释掉一行并重新 运行 服务器之后,我才发现只有当content-type 设置为 'plain/text'
下载是否发生。 res.send()
里面的内容无关紧要,当内容类型为 plain/text 时,/search/
之后的文本会下载到我的机器上。
重新排列路由得到了相同的结果(除了下载之外一切正常。)
应用程序只是挂在 /search/foo
之前到达的任何路线,但下载仍然可以进行。
我的代码:
'use strict';
var express = require('express');
var path = require('path');
var app = express();
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname+'/index.html'));
});
app.get('/search', function(req,res){
res.send('search route');
});
app.get('/search/*', function(req, res, next) {
res.setHeader('content-type', 'plain/text');
var type = typeof(res);
var reqParams = req.params;
res.send(type);
});
var server = app.listen(process.env.PORT || 3000, function(){
console.log('app listening on port ' + process.env.PORT + '!');
});
module.exports = server;
其他详情
- Express 版本 4.15.2
- 节点版本 4.7.3
- 使用 Cloud9
- 我是 Express 新手
- 我的 repo 是 here,在分支 "so_question"
下
定义路由的顺序在 express 中很重要,您可能需要将默认的“/”路由移到“/search/*”路由之后。
Why do some invalid types trigger an error...
因为 MIME 类型有它应该遵循的格式(记录在 RFC 2045 中),而触发错误的类型与该格式不匹配。
格式如下:
type "/" subtype *(";" parameter)
所以有一个强制类型、一个强制斜杠、一个强制子类型和以分号为前缀的可选参数。
但是,当 MIME 类型与该格式匹配时,它仅在句法上有效,不一定在语义上有效,这将我们带到问题的第二部分:
...and other invalid types bypass the error and trigger a download?
从 RFC 2049 中所写:
Upon encountering any unrecognized Content-Type field, an implementation must treat it as if it had a media type of "application/octet-stream" with no parameter sub-arguments. How such data are handled is up to an implementation, but likely options for handling such unrecognized data include offering the user to write it into a file (decoded from its mail transport format) or offering the user to name a program to which the decoded data should be passed as input.
(强调我的)
我正在制作一个相当简单的 Express 应用程序,只有几条路线。我的问题不是关于应用程序的功能,而是关于 Express 路线的一些奇怪行为。
当我启动服务器并使用 /search/*
路由或任何接受参数的路由时,我将这四种内容类型之一应用于响应:
res.setHeader('content-type', 'plain/text');
res.setHeader('content-type', 'plain/html');
res.setHeader('content-type', 'html/plain');
res.setHeader('content-type', 'html/text');
参数作为文件下载,没有任何提示。因此,使用 search/foobar
会下载一个名为 "foobar" 的文件,其大小为 6 字节且文件类型不受支持。现在我明白这四种类型中的 none 是实际的 MIME 类型,我应该使用 text/plain
或 text/html
,但为什么要下载?这两种 MIME 类型的行为与它们应该的一样,并且以下具有类型但没有子类型的 MIME 类型都像它们应该的那样失败,它们都是 return 错误 TypeError: invalid media type
:
res.setHeader('content-type', 'text');
res.setHeader('content-type', 'plain');
res.setHeader('content-type', 'html');
为什么某些无效类型会触发错误,而其他无效类型会绕过错误并触发下载?
到目前为止我发现了什么:
我在 Express 4.x 文档中发现 res.download(path [, filename])
将路径中的文件作为“附件”传输,并且通常会提示用户下载,但这种下载既不是提示也不是故意的.
我无法在 Express 文档(或此处的 SO)中找到任何类似的情况,其中 运行 路由导致文件自动下载到您的计算机。
起初我以为 res.send(typeof(res));
行导致了下载,但是在一次注释掉一行并重新 运行 服务器之后,我才发现只有当content-type 设置为 'plain/text'
下载是否发生。 res.send()
里面的内容无关紧要,当内容类型为 plain/text 时,/search/
之后的文本会下载到我的机器上。
重新排列路由得到了相同的结果(除了下载之外一切正常。)
应用程序只是挂在 /search/foo
之前到达的任何路线,但下载仍然可以进行。
我的代码:
'use strict';
var express = require('express');
var path = require('path');
var app = express();
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname+'/index.html'));
});
app.get('/search', function(req,res){
res.send('search route');
});
app.get('/search/*', function(req, res, next) {
res.setHeader('content-type', 'plain/text');
var type = typeof(res);
var reqParams = req.params;
res.send(type);
});
var server = app.listen(process.env.PORT || 3000, function(){
console.log('app listening on port ' + process.env.PORT + '!');
});
module.exports = server;
其他详情
- Express 版本 4.15.2
- 节点版本 4.7.3
- 使用 Cloud9
- 我是 Express 新手
- 我的 repo 是 here,在分支 "so_question" 下
定义路由的顺序在 express 中很重要,您可能需要将默认的“/”路由移到“/search/*”路由之后。
Why do some invalid types trigger an error...
因为 MIME 类型有它应该遵循的格式(记录在 RFC 2045 中),而触发错误的类型与该格式不匹配。
格式如下:
type "/" subtype *(";" parameter)
所以有一个强制类型、一个强制斜杠、一个强制子类型和以分号为前缀的可选参数。
但是,当 MIME 类型与该格式匹配时,它仅在句法上有效,不一定在语义上有效,这将我们带到问题的第二部分:
...and other invalid types bypass the error and trigger a download?
从 RFC 2049 中所写:
Upon encountering any unrecognized Content-Type field, an implementation must treat it as if it had a media type of "application/octet-stream" with no parameter sub-arguments. How such data are handled is up to an implementation, but likely options for handling such unrecognized data include offering the user to write it into a file (decoded from its mail transport format) or offering the user to name a program to which the decoded data should be passed as input.
(强调我的)