Nodejs Express 静态文件中间件在 IE 含中文的 GET 请求时出现 Bad Request

Nodejs Express 静态文件中间件在 IE 含中文的 GET 请求时出现 Bad Request

确切说是 soundmanager2 的 fallback 模式通过 Flash 请求一个文件 在 Chrome 里是正常的, 不确定是因为 Flash 请求还是 IE 内核的关系 我抓了 req.url 出来是下面这样, 以及对应的报错:

/s/mp3/%D7%B7%C3%CE%C8%CB.mp3
Error: Bad Request
    at SendStream.error (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/node_modules/send/lib/send.js:142:16)
    at SendStream.pipe (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/node_modules/send/lib/send.js:295:31)
    at Object.static (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/lib/middleware/static.js:83:8)
    at next (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/lib/proto.js:190:15)
    at pass (/opt/app/feel-dev/server/node_modules/express/lib/router/index.js:108:24)
    at Router._dispatch (/opt/app/feel-dev/server/node_modules/express/lib/router/index.js:170:5)
    at Object.router (/opt/app/feel-dev/server/node_modules/express/lib/router/index.js:33:10)
    at next (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/lib/proto.js:190:15)
    at Object.handle (/opt/app/feel-dev/server/server.coffee:16:12)
    at next (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/lib/proto.js:190:15)

soundmanager2 的报错是

SMSound._onload(): "/s/mp3/追梦人.mp3" failed to load? 

express 服务器上的脚本片段是:

app.use (req, res, next) ->
  # req.url = decodeURI req.url
  show req.url
  next()

app.use '/s', express.static(__dirname + '/..')
app.use '/s', express.directory(__dirname + '/..')

这种错误好邪门的感觉

然后我尝试直接用 IE 访问 mp3 文件对应网址… 自动调用 Media Player 打开了 难道还是 Flash 问题… 不知道通过中间件有没有办法解决.?


2 回复

标题:Node.js Express 静态文件中间件在 IE 中含中文的 GET 请求时出现 Bad Request

内容: 在使用 Node.js 和 Express 框架时,遇到一个奇怪的问题:当使用 SoundManager2 的 fallback 模式并通过 Flash 请求包含中文字符的文件时,在 Chrome 浏览器中一切正常,但在 IE 中却出现了 Bad Request 错误。经过分析,发现 req.url 是如下形式:

/s/mp3/%D7%B7%C3%CE%C8%CB.mp3

错误信息如下:

Error: Bad Request
    at SendStream.error (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/node_modules/send/lib/send.js:142:16)
    at SendStream.pipe (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/node_modules/send/lib/send.js:295:31)
    at Object.static (/opt/app/feel-dev/server/node_modules/express/node_modules/connect/lib/middleware/static.js:83:8)
    ...

SoundManager2 报错信息如下:

SMSound._onload(): "/s/mp3/追梦人.mp3" failed to load?

服务器端的代码片段如下:

app.use (req, res, next) ->
  # req.url = decodeURI req.url
  console.log req.url
  next()

app.use '/s', express.static(__dirname + '/..')
app.use '/s', express.directory(__dirname + '/..')

为了解决这个问题,可以在中间件中对 URL 进行解码处理。具体来说,可以注释掉 req.url 的解码部分,并添加一行代码来手动解码 URL。

修改后的代码如下:

app.use (req, res, next) ->
  req.url = decodeURI(req.url)
  console.log req.url
  next()

app.use '/s', express.static(__dirname + '/..')
app.use '/s', express.directory(__dirname + '/')

通过上述修改,我们可以确保在处理 URL 时正确地解码中文字符,从而避免 Bad Request 错误的发生。这样可以确保在 IE 中也能正确地访问包含中文字符的静态资源文件。


在IE中使用Node.js Express的静态文件中间件处理包含中文字符的GET请求时,可能会遇到Bad Request的错误。这是因为IE在处理URL编码时可能与Node.js Express不兼容,导致某些字符被误解析。

解决方案

为了解决这个问题,可以在中间件中对req.url进行解码,然后再传递给静态文件中间件。以下是修改后的代码示例:

const express = require('express');
const path = require('path');

const app = express();

app.use((req, res, next) => {
  // 对 req.url 进行解码
  req.url = decodeURI(req.url);
  console.log(req.url); // 用于调试
  next();
});

// 使用静态文件中间件
app.use('/s', express.static(path.join(__dirname, '..')));

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

解释

  1. 解码URL

    • decodeURI(req.url):将URL解码,确保中文字符被正确解析。
  2. 中间件顺序

    • 确保解码中间件在静态文件中间件之前执行。
  3. 调试

    • console.log(req.url):用于调试,查看解码后的URL是否正确。

其他建议

  • 检查Flash版本:如果问题仍然存在,可能需要检查Flash播放器的版本或配置,确保它能够正确处理这些URL。
  • 使用其他媒体播放库:如果问题依然无法解决,可以考虑使用其他媒体播放库(如HTML5 Audio)来替代SoundManager2。

通过上述方法,可以解决IE中因URL编码问题导致的Bad Request错误。

回到顶部