想同时使用GET和POST方法

11

我知道使用GET方法的结果页面可以被加为书签,而使用POST的不能。我也了解到使用GET方法有一些限制。

现在假设我想构建一个搜索引擎,默认情况下使用GET允许用户进行书签标记,但当搜索短语的长度超过限制时,切换到POST。在服务器端,我根据设置使用$_GET或者$_POST。

这可行吗?
如果不行,为什么?
如果可以,请提供简要概述。

谢谢


你想在哪里做决定 - 在服务器端还是客户端(JavaScript)?您是否期望用户执行超过1024个字符的搜索? - ondra
6个回答

13

这是可以做到的,没有问题。

有一个$_REQUEST数组,可将GET、POST和COOKIE值合并,但更好的方式是在脚本中手动处理GET和POST。

只需让引擎检查$_GET ["variable"]$_POST ["variable"],并使用设置的变量。如果在两种方法中都设置了变量,则需要决定您想要给哪个变量优先权。

两种方法之间唯一显着的区别是,GET参数具有大小限制,这取决于浏览器和接收Web服务器(POST也有限制,但通常在几兆字节的范围内)。 我认为一般规则是GET字符串不应超过1024个字符。


3
$_REQUEST 安全问题: http://thephpcode.blogspot.com/2008/09/request-security-problem.html本文讨论了在使用 $_REQUEST 变量处理表单数据时可能出现的安全问题。攻击者可以通过伪造请求来篡改变量值或执行恶意代码,因此建议开发人员避免使用 $_REQUEST 并采用明确的 HTTP 请求方法(如 GET 或 POST)来处理表单数据。同时,应该对接收到的所有数据进行严格验证和过滤,以防止 SQL 注入等攻击。 - mauris
@Pekka:但是我应该在表单方法参数中使用什么?我应该使用JS来检查是否超出了限制,如果是的话..将其从默认的GET更改为POST吗? - gameover
1
你需要使用Javascript来完成这个任务。请查看http://docs.jquery.com/Ajax/serialize以获取表单的(大致)大小。 - Pekka
我不认为$_REQUEST的问题与安全有关。攻击者可以将任何内容放入cookie中,这些内容同样可以很容易地(实际上更容易)放入GET参数中。问题在于如果某个人意外地获得了与表单字段相同名称的cookie,则可能会破坏您的表单,并且用户无法明显地解决该问题。 - bobince
同意。除非有人进行非常糟糕的编程,否则很难通过 $_REQUEST 进行入侵。尽管如此,仍有好几个理由不推荐使用它。 - Pekka
显示剩余2条评论

11

这是如何同时使用GET和POST的示例:

<form action="myfile.php?var1=get1&amp;var2=get2&amp;var3=get3" method="post">

    <input type="hidden" name="var1" value="post1" />
    <input type="hidden" name="var2" value="post2" />

    <input type="submit" />
</form>

这是PHP代码:

print_r($_REQUEST);
// var1 = "post1"
// var2 = "post2"
// var3 = "get3"

print_r($_GET)
// var1 = "get1"
// var2 = "get2"
// var3 = "get3"

print_r($_POST);
// var1 = "post1"
// var2 = "post2"

1
你可以使用类似以下的代码:
<?php
function getParam($key)
{    
    switch (true) {
        case isset($_GET[$key]):
            return $_GET[$key];
        case isset($_POST[$key]):
            return $_POST[$key];
        case isset($_COOKIE[$key]):
            return $_COOKIE[$key];
        case isset($_SERVER[$key]):
            return $_SERVER[$key];
        case isset($_ENV[$key]):
            return $_ENV[$key];
        default:
            return null;
    }    
} 

您无法控制 $_REQUEST 执行的合并操作,因此可能会导致安全问题,请参见Pakka问题的评论以获取链接。它也是一种方便的方法,可以将$_SERVER和$_ENV绑定在一起,而$_REQUEST则不能实现。这种方法被Zend Framework采用。 - hobodave

1

是可以做到的,尽管(我个人认为)GET变得笨重的限制远远大于提供这么多信息的用户界面无法使用的阈值。此外,您向传统搜索引擎提交的查询越复杂,它解决问题的效果就越好。

但我猜您肯定有您的理由。

从您提供的信息来看,实现这一点最简单的方法是使用javascript在运行时将表单方法从GET更改为POST,例如:

<form method='GET' id='searchform' target='search.php' onsubmit='
  if (document.getElementById("searchdata")) {
    if ((document.getElementById("searchdata").length >$some_threshold) 
         && (document.getElementById("searchform"))) { 
         // 2nd if in case this moved to action for button 
         document.getElementById("searchform").method="POST";
     }
   }
 return true;'>
 <textarea name='searchdata' id='searchdata'>
 </textarea>
 <input type='submit' value='go get it'>
</form>

这也可以很好地降级为非JavaScript客户端。

C。


1
function getQVar($key){
     return isset($_GET[$key]) ? $_GET[$key] : (isset($_POST[$key]) ? $_POST[$key] : null); 
}
echo getQVar("name");

将 $_GET 和 $_POST 交换位置,以优先使用 POST 变量而不是 GET 变量。


1

还有一点需要注意,使用GET方法会引起某些用户的诱惑,他们会试图操纵URL来“看看会发生什么”,因此必须确保您的代码适当地对输入变量进行清理。

当然,您本来就应该这样做;-)。但是使用GET方法时最好加倍警惕。

如果我使用GET方法,通常也会设置一个cookie,并在其中放置某种ID,然后将其与GET列表中的变量进行交叉核对,以确保没有任何关于用户A操纵输入并让他们看到源自用户B的任何问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接