使用 ExpressJS 重写 URL
Posted
技术标签:
【中文标题】使用 ExpressJS 重写 URL【英文标题】:URL Rewriting with ExpressJS 【发布时间】:2013-05-10 20:56:08 【问题描述】:我想在我的 ExpressJS 网站上重写我的 URL。我用过这个插件,https://github.com/joehewitt/express-rewrite,但是不行……
但是,我可能犯了一个错误......
我的 app.js 文件:
var express = require('express')
, index = require('./routes/index.js')
, admin = require('./routes/admin.js')
, contact = require('./routes/contact.js')
, posts = require('./routes/posts.js')
, http = require('http')
, path = require('path')
, hash = require('./auth').hash
, db = require('./models')
, favicons = require('connect-favicons')
, rewriter = require('express-rewrite');
var app = express();
app.configure(function ()
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon(__dirname + '/public/images/FAVICON.ico'));
app.use(favicons(__dirname + '/public/images/apple-touch-icon.png'));
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.cookieSession(
secret: 'SECRET',
cookie: access: false
)
);
app.use(rewriter);
app.use(app.router);
app.use(function(req, res, next)
res.render('404.jade',
title: "404 - Page Not Found",
showFullNav: false,
status: 404,
url: req.url
);
);
);
app.configure('development', function ()
app.use(express.errorHandler());
);
app.get('/', index.index);
app.get('/toto', rewriter.rewrite('/heytoto'));
db.sequelize.sync().complete(function(err)
if (err)
throw err
else
http.createServer(app).listen(app.get('port'), function()
console.log('Express server listening on port ' + app.get('port'))
)
);
我的错误信息:
Express
500 TypeError: Object function app(req, res) app.handle(req, res); has no method 'match'
at Object.rewriter [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express-rewrite/rewrite.js:3:26)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at Object.cookieSession [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js:113:5)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at Object.cookieParser [as handle] (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js:60:5)
at next (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/proto.js:199:15)
at resume (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/static.js:60:7)
at SendStream.error (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/connect/lib/middleware/static.js:73:37)
at SendStream.EventEmitter.emit (events.js:126:20)
at SendStream.error (/Users/anthonycluse/Sites/Anthony-Cluse-Express/node_modules/express/node_modules/send/lib/send.js:147:51)
【问题讨论】:
【参考方案1】:您可以在访问要使用的处理程序之前重写 URL。
app.use(function(req, res, next)
if (req.url === '/toto')
req.url = '/heytoto';
next();
);
app.get('/heytoto', ...);
我使用similar method 使用正则表达式进行 URL 重写。
【讨论】:
【参考方案2】:所以我遇到了同样的问题。我编写了一个在浏览器上使用历史 API 的应用程序,我想将所有非静态 URL 重写回 index.html
。所以对于我做的静态文件:
app.configure(function()
app.use('/', express.static(__dirname + '/'));
);
但是对于历史 API 生成的路径,我做了:
app.get('*', function(request, response, next)
response.sendfile(__dirname + '/index.html');
);
这意味着任何不是 /
中的文件或目录的请求(例如由历史 API 生成的 URL)都不会被重写或重定向,而是将提供 index.html
文件,并且然后做所有的 JS 路由魔术。
希望这与您正在寻找的内容相近吗?
【讨论】:
我无法让它工作,可以帮帮我吗? ***.com/questions/27971489/… 如果我需要使用 regexp 重写,我该怎么办? ***.com/questions/38117026/expressjs-rewrite-regex 但是由于这个如果点击返回json的简单http请求.....此时index.html也会被调用。所以这不是很好的解决方案。【参考方案3】:不使用response.sendfile(..)
的解决方案是使用在app.use(express.static(..))
之前插入的重写中间件,如下所示:
// forward all requests to /s/* to /index.html
app.use(function(req, res, next)
if (/\/s\/[^\/]+/.test(req.url))
req.url = '/index.html';
next();
);
// insert express.static(...)
这样,expressjs 可以正确识别重写。然后static
中间件将负责提供文件。
【讨论】:
【参考方案4】:您可以使用 if 条件检查 url,并使用 app.redirect 重定向到某个 url。
【讨论】:
【参考方案5】:1) 您的重写中间件必须出现在将处理请求的中间件/函数之前。
不起作用:
app.use('/hello', () => sayHello() );
app.use(() => rewriteURLToHello()); //it's too late to try to rewrite a URL to /hello
有效:
app.use(() => rewriteURLToHello()); //we can rewrite a URL to /hello
app.use('/hello', () => sayHello() ); //rewritten URL will be handled here
2) 您的中间件不得绑定到您尝试重写的路径
不起作用:
app.use('/hello', (req, res, next) =>
//'/hello' has been trimmed from req.url
//req.url is / if the request was for /hello
req.url = '/goodbye'; //technically setting full path to /hello/goodbye
next(); //will only call other middleware in the /hello chain
);
app.use('/goodbye', () => sayBye()); //won't work
有效:
app.use((req, res, next) => //runs for every path. Same as .use('/',
//'/hello' has NOT been trimmed from req.url
//req.url is /hello if the request was for /hello
if (req.url.startsWith('/hello'))
req.url = '/goodbye'; //full path now /goodbye
next(); //will continue calling all middleware
);
app.use('/goodbye', () => sayBye()); //will work
【讨论】:
【参考方案6】:试试这个:
app.get('/toto', function(req, res)
res.redirect('/heytoto');
);
【讨论】:
是的,但它是一个重定向......我想重写我的网址我不想使用“res.redirect()”函数。以上是关于使用 ExpressJS 重写 URL的主要内容,如果未能解决你的问题,请参考以下文章
使用 DBRef 示例嵌入 ExpressJS 和 Mongoose Schema
使用 DBRef 示例嵌入 ExpressJS 和 Mongoose Schema