3

是否可以在不重定向的情况下更改 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]
4

3 回答 3

1

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

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

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

除了使用<link>标签之外,还可以通过 HTTPLink标头指定资源之间的关系,即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 历史 API。具体来说,使用history.replaceState方法。我认为其他类型的内容不可能实现类似的效果。

编辑

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

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

另请参阅HTTP 标头字段“Content-Location”的用途是什么?

于 2013-05-08T11:06:31.570 回答
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);
于 2013-05-08T12:36:07.950 回答
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

于 2019-08-08T18:05:43.060 回答