PHP/Apache错误:406不可接受

8
今天我遇到了这个错误,我已经缩小到了这个问题:
我的网站是我的音乐家页面here。它允许人们进来看看我的照片、新闻、我的音乐和我演奏的活动。
一切都很顺利,我手动输入数据到MySQL,以便自动提供给主页。现在我正在添加控制面板,以便我可以从网络上添加、编辑、删除数据库中的内容。
除了添加/编辑活动的能力外,一切正常。我已经缩小到不能同时输入2个URL或者会出现这个错误。我需要输入2个URL(一个用于查看活动页面,一个用于购买门票),但我不能同时输入两个,是否有任何方法可以纠正或解决这个错误,无论是在apache还是我的代码中?
<?php
    $specevlink = "http://facebooklink.com";
    $specgigtick = "http://ticketplacelink.com";
?>
     <form method="post" action="index.php?page=editgigs">
         <table>
                <tr>
                     <td>
                          Event Page (Link):
                     </td>
                     <td style="text-align: left;">
                          <input type="url" name="giglink" value="<?php echo $specevlink; ?>" />
                     </td>
                </tr>
                <tr>
                     <td>
                          Event Tickets (Link):
                     </td>
                     <td style="text-align: left;">
                          <input type="url" name="gigtick" value="<?php echo $specgigtick; ?>" />
                     </td>
                </tr>
         </table><br />
         <input type="submit" name="editgig" value="submit" /><br />
         <br />
     </form>

编辑:

我添加了完整的代码行,这样您就可以看到我正在使用什么了。

这是步骤1的图片。 这是步骤2的图片。

这被包含在一个index.php文件中:

<?php
if(isset($_GET["page"])){
$page = $_GET["page"];
} else {
$page = "";
}

if($page === "editgigs"){
 include ('inc/logincheck.php');
?>
 <div class="label">
      EDIT GIGS
 </div><br />
 <div style="margin: 0 auto; text-align: center; width: 100%">
      <form method="post" action="index.php?page=editgigs">
<?php
      if(!isset($_POST['selectgigs'])){
           if(!isset($_POST['updgigs'])){
?>
                Select one of the options below:<br />
                <br />
                <select name="selgigs" style="max-width: 26%;">
<?php
                     while($gigsall_data = mysqli_fetch_array($gigsall_query)){
                          $gigid = stripslashes($gigsall_data['idgigs']);
                          $gigdate = stripslashes($gigsall_data['date']);
                          $gigname = stripslashes($gigsall_data['name']);
                          $gigdate = date('F j, Y', strtotime($gigdate));
?>
                          <option value="<?php echo $gigid; ?>">
                               <?php echo $gigdate; ?>: <?php echo $gigname; ?>
                          </option>
<?php
                     }
?>
                </select><br /><br />
                <input type="submit" name="selectgigs" value="Select" /><br />
                <br />
<?php
           }
      }
      if(isset($_POST['selectgigs'])){
           $gigtoed = trim($_POST['selgigs']);
           $specgig_query = mysqli_query($con, "SELECT * FROM `gigs` WHERE `idgigs` = '$gigtoed'") or die(mysqli_error($con));
           $specgig_data = mysqli_fetch_array($specgig_query);
           $specdate = stripslashes($specgig_data['date']);
           $specname = stripslashes($specgig_data['name']);
           $specevlink = stripslashes($specgig_data['evlink']);
           $specgigtick = stripslashes($specgig_data['ticklink']);
           $specnos = stripslashes($specgig_data['noshow']);
           if($specnos === '0'){
                $noshow = '';
           } else {
                $noshow = 'checked';
           }
?>
           <table style="border-spacing: 5px; padding: 10px;">
                <tr>
                     <td>
                          Past Event?:
                     </td>
                     <td style="text-align: left;">
                          <input type="checkbox" name="nos" <?php echo $noshow; ?> /> Past Event
                     </td>
                </tr>
                <tr>
                     <td>
                          Date:
                     </td>
                     <td style="text-align: left;">
                          <input type="date" name="gigdate" value="<?php echo $specdate; ?>" required />
                     </td>
                </tr>
                <tr>
                     <td>
                          Name:
                     </td>
                     <td style="text-align: left;">
                          <input type="text" name="gigname" value="<?php echo $specname; ?>" required />
                     </td>
                </tr>
                <tr>
                     <td>
                          Event Page (Link):
                     </td>
                     <td style="text-align: left; width: 350px;">
                          <input type="url" name="giglink" style="width: 100%;" value="<?php echo $specevlink; ?>" />
                     </td>
                </tr>
                <tr>
                     <td>
                          Event Tickets (Link):
                     </td>
                     <td style="text-align: left; width: 350px;">
                          <input type="url" name="gigtick" style="width: 100%;" value="<?php echo $specgigtick; ?>" />
                     </td>
                </tr>
           </table><br />
           <input type="hidden" name="gigid" value="<?php echo $gigtoed; ?>" />
           <input type="submit" name="updgigs" value="Update" /><br />
           <br />
<?php
      }
      if(isset($_POST['updgigs'])){
           $newid = trim($_POST['gigid']);
           $newdate = mysqli_real_escape_string($con, trim($_POST['gigdate']));
           $newname = mysqli_real_escape_string($con, trim($_POST['gigname']));
           $newlink = mysqli_real_escape_string($con, trim($_POST['giglink']));
           $newtick = mysqli_real_escape_string($con, trim($_POST['gigtick']));
           if(isset($_POST['nos'])){
                $newnoshow = mysqli_real_escape_string($con, '1');
           } else {
                $newnoshow = mysqli_real_escape_string($con, '0');
           }
           echo $newid.' '.$newdate.' '.$newname.' '.$newlink.' '.$newtick.' '.$newnoshow.'<br />';
           /*mysqli_query($con, "UPDATE `gigs` SET `date` = '$newdate', `name` = '$newname', `evlink` = '$newlink', `ticklink` = '$newtick', `noshow` = '$newnoshow' WHERE `idgigs` = '$newid' LIMIT 1") or die(mysqli_error($con));*/ //commented for testing
?>
           <div style="text-align: center;">
                <span class="confirm">
                     Successfully updated click <a href="index.php?page=events">here</a> to view it!
                </span>
           </div>
<?php
      }
?>
      </form>
 </div>
<?php
}

FYI- logincheck.php仅用于检查用户是否已登录,如果未登录,则将其发送回主页。

你读过这些问题吗?http://stackoverflow.com/questions/13500686/406-not-acceptable-error-get-parameter-issue 和 https://dev59.com/WWYq5IYBdhLWcg3wui4z - ComFreek
1
是的,我实施了答案/建议,但它没有起作用。 - iam-decoder
这可能对你有所帮助,但我不确定。可以试一下...https://dev59.com/1W_Xa4cB1Zd3GeqP6u6E - Kishore
那里记录的答案也已经实现了,但是没有起作用。 - iam-decoder
1
一个可能的麻烦制造者是您同时发送GET和POST参数。尽管它可能会实际工作,但这不是一个好主意。请尝试使用名为“editgigs”的隐藏输入字段,而不是表单目标“?page=editgigs”。 - cen
显示剩余4条评论
3个回答

6
如果用户输入项以http://https://开头,您的网站将生成错误。
当我尝试使用以http://开头的链接时,我收到了一个406 Not Acceptable错误: http://onkore.us/?blah=http://www.google.com 但是如果我尝试这个链接: http://onkore.us/?blah=www.google.com 就没有问题。
您提到如果有超过一个链接会出现问题,但是当我尝试像下面这样的两个链接时,一切都正常: http://onkore.us/?blah1=www.google.com&blah2=www.google.com 然而,您可以找到并修复可能特定于服务器配置的问题,或者您可以尝试解决问题。
我不确定这个解决方法是否有用,但是考虑到http://https://会导致问题,我的想法是从用户输入中删除http://https://。首先,您可能需要尝试将<input type="url"更改为<input type="text",以便不强制使用URL格式。然后,您可以在提交表单之前使用JavaScript从表单中删除用户输入中的http://https://出现的位置。此外,在填充表单值之前,您可以从数据中删除这些内容。
希望这有所帮助。
正则表达式:如何在JavaScript中从URL中删除'http://'

+1,干得好。我认为他现在唯一可以尝试的就是删除 httpshttp,因为已经尝试过将 input type="url" 更改为 input type="text" 但没有起作用。 - Tomás
还有这个相关的内容:http://stackoverflow.com/questions/13500686/406-not-acceptable-error-get-parameter-issue - Tomás

5
这个错误意味着,例如,你请求服务器提供的是书籍(而且你只懂得西班牙语),但服务器只有英语和德语的书。
因此,服务器有你需要的答案但是不会给你,因为它知道你不会做什么有用的事情,或者你会拿这些书籍去做坏事(例如,把它们扔到人们的头上而不是阅读它们)。

"406 Not Acceptable"是一个不寻常的状态代码 - 最常见的是200、404、500、301。只有在服务器出了问题时才会看到406,通常是一些愚蠢但难以诊断的问题。

此外:

此一般性错误意味着,您所发出的请求被检测为对服务器的潜在攻击企图[...]
https://billing.stablehost.com/knowledgebase/178/What-does-406-Not-Acceptable-mean.html


这个错误最常见的解决方案与mod_security有关。

1. Mod_security

ModSecurity可以实时监控HTTP流量,以便检测攻击[...]它作为Web入侵检测工具运行。ModSecurity还可以立即采取措施,防止攻击到达您的Web应用程序。

这个406错误可能是由于mod_security作为对可能通过POST进行的攻击的响应而发生的,传递一些URL而不是纯文本和正常文本。

最常见的解决方案是在htaccess中禁用POST扫描和mod_security过滤:

<IfModule mod_security.c>
SecFilterEngine Off
SecFilterScanPOST Off
</IfModule>

此外,在终端中执行以下命令:
sudo a2dismod security2_module 
sudo service apache2 restart 

关闭ModSecurity。

如果无法生效,则编辑文件。

/etc/apache2/mod-security/modsecurity_crs_10_config.conf

在类似于以下内容的行的开头添加#

SecDefaultAction “phase:2,log,deny,status:403,t:lowercase,t:replaceNulls,t:compressWhitespace”

最后,重新启动apache:

sudo service apache2 restart


我使用 $_GET["page"]; 来确定页面要显示哪个部分,但是使用隐藏的输入字段并将其发布到 index.php 上并不起作用。我尝试将其设置为包括 $_POST['page'] 并尝试在分页引用中包含它,但仍然无法正常工作。 - iam-decoder
还是遇到了406错误吗?试试这个。将两个输入框的input type="url"改为input type="text"。保留type="hidden"不变。 - Tomás
我也试过那个 :/ 我正在努力添加所有的编码。 - iam-decoder
你刚刚提交的代码第一行缺少 <?php,是吗?(只是确认那不是所有问题的原因) - Tomás
我已经添加了,它在我使用的文件中,所以这不是问题,我也尝试了所有三种编码类型。但都没有起作用 :/ - iam-decoder
显示剩余3条评论

1
我已经遇到这个问题有一段时间了,但只是偶尔出现,所以很难确定。
然而,在进行了一些测试后,我在我的情况下找到了错误。也许在你的情况下不是这样,但如果有人遇到 "406 Not Acceptable" 错误,这是值得一试的。
在我的情况下,每当发布的数据中有 "shell:" 时,就会出现该错误,我猜测这是解释错误并抛出错误。对我来说,解决方案是在发布之前替换该字符串。

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