http - 更改请求网址?

时间:2013-05-08 10:08:27

标签: node.js http

是否可以在没有重定向的情况下更改HTTP请求的URL?

例如,而不是:

请求1

GET /user/abc123/ HTTP/1.1

HTTP/1.1 301 Moved Permanently
Location: /files/abc123

请求2

GET /files/abc123 HTTP/1.1

HTTP/1.1 200 OK
.
.
[filecontent]

我可以直接回复文件,但让客户知道他被重定向:

单一请求

GET /user/abc123/ HTTP/1.1

HTTP/1.1 200 OK
Location: /files/abc123
.
.
[filecontent]

3 个答案:

答案 0 :(得分:1)

据我所知,使用HTTP无法做到这一点。 HTTP中的重定向特别意味着客户端应该发送第二个请求。

我认为您想要的更类似于为某些资源指定“规范网址”,然后在浏览器位置栏中显示此规范网址。

RFC 6596指定了一种使用<link rel="canonical">指定规范网址的方法。但是,它没有指定浏览器应该如何处理它,如果有的话。 Google使用它来更好地选择要索引的网址。

除了使用<link>标记之外,还可以通过HTTP Link标题指定资源之间的关系,即Link: </better-url>; rel=canonical。见http://www.w3.org/wiki/LinkHeader。我不确定这是否会被Google收录。 http://support.google.com/webmasters/bin/answer.py?hl=en&answer=139394上的页面未提及Google支持该页面。浏览器肯定会忽略它,因为几乎任何链接标签,样式表都是值得注意的例外。

如果相关内容是HTML文档,您可以使用HTML5 history API进行此操作。具体来说,使用history.replaceState方法。我不认为与其他类型的内容实现类似的东西。

修改

Content-Location标题实际上可能非常适合您想要的内容。 来自HTTP 1.1 RFC的第14.14节:

  

当从与请求资源的URI分开的位置访问该实体时,Content-Location实体头字段可用于为消息中包含的实体提供资源位置。服务器应该为与响应实体对应的变体提供内容位置;特别是在资源具有与之关联的多个实体的情况下,并且这些实体实际上具有可以单独访问它们的单独位置,服务器应该为返回的特定变体提供内容位置。

  Content-Location = "Content-Location" ":"
                     ( absoluteURI | relativeURI )
     

Content-Location的值还定义了实体的基URI。

     

Content-Location值不是原始请求URI的替代值;它只是在请求时对应于该特定实体的资源的位置的声明。如果希望识别特定实体的来源,则未来请求可以将Content-Location URI指定为request-URI。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

另见What is the purpose of the HTTP header field “Content-Location”?

答案 1 :(得分:1)

嗯, 可能,但感觉有点脏。

快速演示:

var express = require('express');
var app     = express();

app.get('/user/abc123', function(req, res, next) {
  req.path = req.url = '/files/abc123';
  next();
});

app.get('/files/abc123', function(req, res) {
  res.set('Location', req.url);
  res.send('files!');
});

app.listen(3012);

答案 2 :(得分:0)

这是我的简单方法,不仅更改了originalUrl,还更改了path。我的方法建议:

app.use(function(req, res, next) {
    console.log("request", req.originalUrl);
    const removeOnRoutes = '/not-wanted-route-part';
    req.originalUrl = req.originalUrl.replace(removeOnRoutes,'');
    req.path = req.path.replace(removeOnRoutes,'');
    return next();
});

通过这种方式,/not-wanted-route-part/users将变成/users