是否可以重定向帖子数据?

Posted

技术标签:

【中文标题】是否可以重定向帖子数据?【英文标题】:Is it possible to redirect post data? 【发布时间】:2010-09-26 08:59:09 【问题描述】:

我有一个网站,所有请求都被静默(通过.htaccess)重定向到index.php,然后使用PHP 显示正确的页面(通过解析REQUEST_URI)。

我想知道是否也可以将 POST 数据提交到假地址?

我目前的表格是这样的......

<form action="/send-mail" method="post">

而我的.htaccess 规则是……

# redirect mail posting to index
RewriteRule send-mail index.php?send-mail [NC,L] 

我的index.php 检查isset($_GET['send-mail']) 工作正常。

然而,这似乎丢弃了所有应该发送给它的 POST 数据。

有没有办法保留帖子数据?我不想使用 GET,因为它无法发送尽可能多的信息,尽管使用简单的查询表单可能不是问题。

这是我的.htaccess,用于重定向到index.php

# serve files and dirs if they exist please, otherwise send to index
RewriteCond %REQUEST_FILENAME !-d
RewriteCond %REQUEST_FILENAME !-f
RewriteRule . index.php

【问题讨论】:

【参考方案1】:

试试这个:

# redirect mail posting to index
     RewriteRule send-mail index.php?send-mail [NC,P]

“P”的作用类似于“L”,它停止处理规则,但它也告诉模块该请求应原封不动地传递给代理模块(意味着保留 POST 数据)。

【讨论】:

请注意,您需要启用代理模块,并在配置文件中启用 proxy_http_module 才能使其工作。此外,您可能需要设置重写规则的绝对路径。也就是说,在上面的示例中,您将使用RewriteRule send-mail /path/to/index/index.php?send-mail [NC,P](或至少在索引之前使用/ 如果您希望保留 Host 标头,您还需要在 apache 配置中启用 ProxyPreserveHost On 似乎同时代理也适用于文档中指出的 URL:httpd.apache.org/docs/2.4/rewrite/proxy.html 我花了 3 天时间试图弄清楚为什么 POST 数据没有被转发。 [P] 完成了这项工作。谢谢。【参考方案2】:

您应该能够简单地重定向到index.php,然后在该脚本中访问$_SERVER['REQUEST_URI'] 以查看原始请求,并且“发送邮件”完好无损。

顺便说一句,“不能发送尽可能多的信息”不是使用 POST 的原因。使用 POST 的原因是该请求将修改您网站上的数据,而不是简单地检索数据。

假设您在页面上放置了一个带有 GET 请求(如“/delete_user?id=1234”)的超链接,然后某个搜索引擎在为您的网站编制索引时无辜地跟踪该链接。这就是为什么 GET 请求不适用于修改数据的请求。

【讨论】:

有一个小限制,一旦你达到某个任意限制(我认为它的 1024 个字符),它后面的数据就会从请求中删除。如果它恰好是用户输入字段,则尤其成问题。 (注意:限制是服务器浏览器特定的,RFC 说它是无限的,但我们知道一些公司阅读的频率) +1 自从我问了这个问题后,我有点开明了,现在完全理解所有数据修改都应该是 POST【参考方案3】:

我发现最可靠的方法是使用307 状态码。

RewriteRule send-mail index.php?send-mail [R=307,L]

状态码 307 表示应使用相同的 HTTP 方法和数据重复请求。因此,如果您使用此状态码,您的 POST 请求将连同其数据一起重复。

如果您需要为非POST 请求支持标准301 重定向,您也可以检测请求是否为POST 请求。

# POST requests.
RewriteCond %REQUEST_METHOD POST
RewriteRule send-mail index.php?send-mail [R=307,L]

# Standard GET requests.
RewriteRule send-mail index.php?send-mail [R=301,L]

【讨论】:

正如你所说。谢谢你的提示。 (详情w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8)【参考方案4】:

为避免某些代理和 Apache 重写出现问题,请传入 POST 数据或为正文为空的请求设置 Content-Length: 0 标头。

我最近在使用空主体执行 POST 时遇到 Apache 将我的请求转换为 GET 的问题。所以,而不是这个:

 curl -X POST https://example.com/api/user/123456789

传递Content-Length 标头:

 curl -X POST https://example.com/api/user/123456789 -H 'Content-Length: 0'

或在体内传递一些东西:

 curl -X POST https://example.com/api/user/123456789 -d ''

【讨论】:

【参考方案5】:

只要您只使用内部重写,而不是 HTTP 重定向,就不会丢失 POST 数据。这是我在我的网站上使用的规则:

RewriteRule ^(.*)$ index.php/$1 [L]

尝试使用 Firefox 的 HTTPLiveHeaders 扩展(或类似的东西)并跟踪整个页面请求。确保您没有收到 HTTP 重定向。如果您收到 HTTP/1.1 3xx 响应和 Location: http://address 标头,那就是问题所在。您发布的重写规则不应导致这种情况发生。如果您被重定向,则可能是您的 PHP 代码中存在错误或正在应用另一个重写规则。

【讨论】:

不,我回来了 200 OK :S 看起来浏览器将在重定向后使用GET 进行第二个请求... 没有第二个重写请求。只有重定向(位置标头和 3xx 响应)有第二个请求。【参考方案6】:

我想将 user_login.php 重定向到 seo 友好的 url,如 /user-login 和发布表单数据,这对我有用。

RewriteCond %THE_REQUEST ^[A-Z]3,\s/user_login\.php [NC]
RewriteRule ^ user-login [QSA,R=301]
RewriteRule ^user-login$ user_login.php [QSA,L]

在视图文件中

<form action="<?php $siteurl;?>/user-login" method="post" id="user_login">

【讨论】:

以上是关于是否可以重定向帖子数据?的主要内容,如果未能解决你的问题,请参考以下文章

Rails在破坏行动后重定向

重定向 HTTP 表单帖子

表单验证重定向问题

如何将自定义帖子类型的帖子重定向到一个网址?

更新帖子后,我希望将用户重定向到帖子(Django - Python)

使用 .htaccess 重定向 URL 而不使用尾随帖子 ID