【问题标题】:url parsing in express.jsexpress.js 中的 url 解析
【发布时间】:2019-05-02 18:10:18
【问题描述】:

我正在尝试在我的节点服务器上学习 express.js,并尝试将同样的东西从 http 模块复制到 express 框架中。

进一步解释: 在开始使用 express 之前,我使用的是第一个代码,其中我在“站点”文件夹中有一个文件树,其中包含诸如

之类的网页
e:
|_node.js
   |_node_modules
   |_site
   | |_abc
   | | |_123.html
   | | |_456.html
   | | |_789.html
   | |_cde
   | | |_123.html
   | | |_456.html
   | | |_789.html
   | |_abc.html
   | |_cde.html
   |_server.js

我通常只需让 localhost:8080/abc/123 获取 /site/abc/123.html 即可在 url 中访问它们。

var http = require('http');
var url = require('url');
var fs = require('fs');
var port = 8080;

http.createServer(function (req, res) {
  var q = url.parse(req.url, true);
  var filename = "./site" + q.pathname + ".html";
  fs.readFile(filename, function(err, data) {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'});
      return res.end("404 Not Found");
    }  
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(data);
    return res.end();
  });
}).listen(port);
console.log('Running on port ' + port);

这里,我试过这样做

var url = require('url');
var fs = require('fs');
var express = require('express');
var app = express();
var port = 8080;
var site = "/site"

app.get('*', function (req, res) {
  var q = url.parse(req.url, true);
  var filename = site + q.pathname + ".html";
    fs.readFile(filename, function(err, data) {
    if (err) {
      console.log(err);
      res.writeHead(404, {'Content-Type': 'text/html'});
      return res.end("404 Not Found");
    }  
    res.writeHead(200, {'Content-Type': 'text/html'});
      res.sendFile(filename, { root: __dirname + site } );
    return res.end();
  });
})

var server = app.listen(port, function () {
    console.log('Running on port ' + port);
})

但是现在当我输入 localhost:8080/abc/123 时使用 express 框架,但它只返回 404 Not Found 输入http://localhost:8080/abc

显然错误包含

{[Error: ENOENT: no such file or directory, open 'e:\site\abc.html']
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'e:\\site\\abc.html'}

完整路径应该是

e:\node.js\site\abc.html

server.js 位于 e:\node.js

为什么它在 e: 处比在 e:\node.js 处跳回

现在我猜测“root: __dirname”会导致错误,我应该用什么替换它以便它从 e:/node.js 而不是 e: 开始?

【问题讨论】:

  • 您能否编辑您的问题以阐明您所期望的以及什么不起作用?目前尚不清楚实际问题是什么。
  • 更新了我的问题,抱歉。在开始使用 express 之前,我使用的是第一个代码,其中我有一个文件树,其中包含 /abc/123.html、/cbe/234.html 等网页,我通常只需通过 localhost:8080/abc 在 url 中访问它们/123 获取 /abc/123.html。但是现在使用 express 框架,当我输入 localhost:8080/abc/123 时,它会返回 Cannot GET /abc/123

标签: javascript node.js express


【解决方案1】:

变化:

var site = "/site"

到:

var site = "site"

根选项仅适用于相对文件名,但以“/”开头的路径是文件系统根的绝对路径。

除非你需要对文件做更多的事情,如果你只是为它们提供服务,最好使用 express.static() 来提供它们,它可以配置为不暴露 .html 扩展名,如下所示:

https://stackoverflow.com/a/37990843/2106611

【讨论】:

  • 谢谢,但现在我正试图弄清楚为什么代码在 http 模块上工作而不是在 express 上工作。但可以肯定的是,这在未来会派上用场
  • 我已经编辑了答案,试图解决具体问题
【解决方案2】:

这可能不是唯一的问题,但有一件事是

app.get('/', ... 

只会匹配根 url,所以它会匹配 localhost:8080/ 而不是 localhost:8080/foo 或任何其他路径。

app.getaccepts a string, path pattern or regular expression.

要匹配 任何东西,您需要这样做:

app.get('/*', ... 

或者如果您只想匹配以某个段开头的路径,您可以这样做:

app.get('/some-path/*', ...

这将匹配localhost:8080/some-path/、localhost:8080/some-path/foo、localhost:8080/some-path/bar 等。

编辑:

关于为什么你得到错误的文件路径,如果你仔细观察你会发现你只是在尝试发送文件时使用__dirname,而不是在你发送文件的时候。重读!

所以你有:

var filename = site + q.pathname + ".html";
    // This is not reading from the correct path -
    // it's missing __dirname!
    fs.readFile(filename, function(err, data) {

应该改成

var filename = __dirname + site + q.pathname + ".html";
    // This is now using __dirname which should be the
    // the directory of your server module
    fs.readFile(filename, function(err, data) {

然后再往下,您不需要使用sendFile,因为您已经在变量中拥有data,您可以使用与您的示例类似的代码:

res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
return res.end();

【讨论】:

  • 我尝试使用 app.get('*', ... 但我只得到 404 Not Found
  • 这意味着它会通过你的解析器?您应该能够通过打印出 err 变量来调试您的视图,然后找出它为什么找不到所需的文件。
  • 显然错误包含``` {[Error: ENOENT: no such file or directory, open 'e:\site\abc.html'] errno: -4058, code: 'ENOENT', syscall: 'open', path: 'e:\\site\\abc.html'}``` 完整路径应该是 e:\node.js\site\abc.html 并且 server.js 位于 e :\node.js 为什么它在 e: 处比在 e:\node.js 处跳回
  • 我已经更新了我的答案。您通常应该检查您的错误在哪一行,您假设它是在 res.sendFile(filename, { root: __dirname + site } 引发的,但它可能是由 fs.readFile(filename, function(err, data) { 引发的
  • 这完全帮助了我。我从我所做的搜索中拼接了一些结果并最终使用了路径模块,但是您的解决方案看起来比我的解决方案更干净整洁。谢谢!
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-20
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多