【问题标题】:How to prevent form resubmission when page is refreshed (F5 / CTRL+R)页面刷新时如何防止表单重新提交(F5 / CTRL+R)
【发布时间】:2011-09-13 06:56:24
【问题描述】:

我有一个向我的 SQL 表提交文本的简单表单。问题是用户提交文本后,他们可以刷新页面并再次提交数据,而无需再次填写表单。提交文本后,我可以将用户重定向到另一个页面,但我希望用户留在同一页面上。

我记得读过一些关于为每个用户提供唯一会话 ID 并将其与另一个值进行比较的内容,这解决了我遇到的问题,但我忘记了它在哪里。

【问题讨论】:

  • 为什么不想将用户重定向到另一个页面?
  • @Adam:因为这对于向服务器发出另一个请求是多余的,而服务器又会再次从数据库中获取一些数据。但这是资源浪费,因为我们在处理 POST 请求时已经获取了所有需要的数据
  • @EugenKonkov 在 PRG 模式中,您只需重定向到显示成功消息的页面。无需进一步从数据库中获取。
  • @Adam:您也可以显示由POSTing 数据创建的整个记录​​。在这种情况下,您需要从 DB 中 SELECT 它。例如,当您创建发票时,您将被重定向到 /invoices/53,它会显示整个发票,而不仅仅是“成功”

标签: php html forms post form-submit


【解决方案1】:

我还想指出,您可以使用 javascript 方法 window.history.replaceState 来防止在刷新和返回按钮上重新提交。

<script>
    if ( window.history.replaceState ) {
        window.history.replaceState( null, null, window.location.href );
    }
</script>

此处的概念证明:https://dtbaker.net/files/prevent-post-resubmit.php(链接不再有效)

我仍然会推荐 Post/Redirect/Get 方法,但这是一种新颖的 JS 解决方案。

【讨论】:

  • 谢谢,@dtbaker,太棒了:)
  • Tks,这对我来说是完美的工作,它只需要创建 404 页面避免用户误解
  • 简直太棒了。谢谢你
  • 它在 safari 中不起作用,它改变了 href 但仍然保留了 post 请求提交的数据
  • 这对我有用,谢谢!为什么推荐 PRG 方法?
【解决方案2】:

使用发布/重定向/获取模式。 http://en.wikipedia.org/wiki/Post/Redirect/Get

对于我的网站,我会将消息存储在 cookie 或会话中,在发布后重定向,读取 cookie/会话,然后清除该会话或 cookie 变量的值。

【讨论】:

  • 这使得 chrome 无法用于业务只需要一个帖子的开发!
  • 如果你使用PRG模式,那么你真的离开了页面,对吧?问题不是在不重定向时如何使事情正常工作吗?
  • 在我看来,如果您重定向到同一页面,那么 $_POST 将被清除。据我了解,这是预期的效果。无论如何,那是我想要的效果。不过,我认为如果它明确表示答案会更好。
  • 效果很好,我唯一的建议是确保启用严格的错误测试,以便在开发时在本地捕获错误,否则它们可能会被忽视。
  • 使用 PRG,你会失去上下文,这对我来说是一个糟糕的解决方案。我们不应该那样做。
【解决方案3】:

您可以通过会话变量防止表单重新提交。

首先,您必须在文本框中设置rand(),并在表单页面上设置$_SESSION['rand']

<form action="" method="post">
  <?php
   $rand=rand();
   $_SESSION['rand']=$rand;
  ?>
 <input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
   Your Form's Other Field 
 <input type="submit" name="submitbtn" value="submit" />
</form>

之后检查 $_SESSION['rand'] 与文本框 $_POST['randcheck'] 值 像这样:

if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
{
    // Your code here
}

确保在使用 session_start() 的每个文件上启动会话

【讨论】:

  • 我们可以改用&lt;input type="hidden" name="randcheck" id="randcheck" value="&lt;?php echo microtime(); ?&gt;" /&gt;
  • 是的,我们可以使用 microtime() 和 time() 来代替 rand() ,无论我们可以使用任何提供不同值的函数或变量。但请确保将该值设置为 SESSION 变量。这里 SESSION 是必须检查 randcheck 字段并防止重新提交表单。
  • 在检查 session 和 post vars 是否匹配后不应该清除 session 变量吗?
  • @denoise 我相信@Savoo 的想法是,在表单数据的$_POST 之后,相同的页面会重新加载,重新设置会话和发布变量。在检查变量是否匹配后,还应创建变量。因此不需要unset
  • 我目前正在使用这种方法,带有令牌。但是,这会在多选项卡提交时产生问题。由于它将在每个选项卡上创建新的rand(),并覆盖会话值,这意味着打开的旧选项卡不再有效。有什么建议吗?
【解决方案4】:

这种方法对我很有效,我认为这是最简单的方法。

一般的想法是在表单提交后将用户重定向到其他页面,这将在页面刷新时停止表单重新提交。尽管如此,如果您需要在提交表单后将用户保持在同一页面上,您可以通过多种方式进行,但这里我描述的是 JavaScript 方法。


JavaScript 方法

这种方法非常简单,一旦提交表单,就会阻止在刷新时要求重新提交表单的弹出窗口。只需将这行 JavaScript 代码放在文件的页脚即可看到“魔法”。

<script>
if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}
</script>

【讨论】:

  • 这对我也有帮助
  • 这在 Safari 中是否已修复? stackoverflow.com/a/54799886
  • 公然复制+粘贴以前的答案(见@Mo'men的答案)
【解决方案5】:

我使用此 javascript 行来阻止在提交表单后要求在刷新时重新提交表单的弹出窗口。

if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}

只需将这一行放在文件的页脚处,看看它的神奇之处

【讨论】:

  • 一个不能从客户端禁用的版本会很好,但它简短、简单、快速......并且可以做它需要做的事情。保留历史记录,以便用户可以向后导航,而无需重新发送帖子。
  • 这为我解决了这个问题。这种方法有什么缺点吗?
【解决方案6】:

您确实应该使用 Post Redirect Get 模式来处理此问题,但如果您以某种方式最终处于 PRG 不可行的位置(例如,表单本身位于包含中,防止重定向),您可以散列一些请求参数根据内容生成一个字符串,然后检查你是否还没有发送它。

//create digest of the form submission:

    $messageIdent = md5($_POST['name'] . $_POST['email'] . $_POST['phone'] . $_POST['comment']);

//and check it against the stored value:

    $sessionMessageIdent = isset($_SESSION['messageIdent'])?$_SESSION['messageIdent']:'';

    if($messageIdent!=$sessionMessageIdent){//if its different:          
        //save the session var:
            $_SESSION['messageIdent'] = $messageIdent;
        //and...
            do_your_thang();
    } else {
        //you've sent this already!
    }

【讨论】:

  • 感谢分享,但这似乎不起作用。刷新页面确实会为我重新提交表单。也许我错过了什么?
  • 刷新页面将重新提交所有内容,但我们只选择处理与上次发送的数据不同的提交数据(我们存储在 session var 'messageIdent' 中)。您是否在“if messageIdents are different”子句中处理表单提交(即“do_your_thang()”在哪里)?
  • 感谢您的回复。我最终只是实现了 Post / Redirect / Get 模式,所以,我现在不记得到底是什么绊倒了我。不过,再次感谢您回访。
  • 这个方法不是为了阻止重新提交......而是为了检测重新提交,这样你就可以改变你的代码,不要“做”任何你会做的事情,如果这是一个新的提交。换句话说:使用这种方法,您可以检测“原始”提交并放置您的数据。如果它不是原创的,请不要放置您的数据。要么显示“欺骗尝试”警告,要么显示“确认”。
  • 要使这个工作,您必须通过在文件开头添加session_start(); 来启动会话。 w3schools.com/php/php_sessions.asp注意: session_start() 函数必须是文档中的第一件事。在任何 HTML 标记之前。
【解决方案7】:

当表单被处理时,你重定向到另一个页面:

... process complete....
header('Location: thankyou.php');

您也可以重定向到同一页面。

如果您正在做类似 cmets 的操作,并且希望用户停留在同一页面上,您可以使用 Ajax 来处理表单提交

【讨论】:

    【解决方案8】:

    我找到了下一个解决方法。在处理POST 请求后,您可以通过操作history 对象来逃避重定向。

    所以你有了 HTML 表单:

    <form method=POST action='/process.php'>
     <input type=submit value=OK>
    </form>
    

    当您在服务器上处理此表单时,您无需通过设置 Location 标头将用户重定向到 /the/result/page,如下所示:

    $cat process.php
    <?php 
         process POST data here
         ... 
         header('Location: /the/result/page');
         exit();
    ?>
    

    处理POSTed 数据后,您会渲染小&lt;script&gt; 和结果/the/result/page

    <?php 
         process POST data here
         render the <script>         // see below
         render `/the/result/page`   // OK
    ?>
    

    你应该渲染的&lt;script&gt;

    <script>
        window.onload = function() {
            history.replaceState("", "", "/the/result/page");
        }
    </script>
    

    结果是:

    如您所见,表单数据是 POSTed 到 process.php 脚本。
    此脚本一次处理POSTed 数据并渲染/the/result/page

    1. 无重定向
    2. 刷新页面(F5)时没有rePOST数据
    3. 当您通过浏览器历史导航到上一页/下一页时,没有回复POST

    UPD

    作为另一种解决方案,我要求 Mozilla FireFox 团队的feature request 允许用户设置NextPage 标头,该标头将像Location 标头一样工作,并使post/redirect/get 模式过时。

    简而言之。当服务器处理表单POST数据成功时:

    1. 设置NextPage 标头而不是Location
    2. 呈现处理POST 表单数据的结果,就像它在post/redirect/get 模式中呈现GET 请求一样

    浏览器依次看到NextPage标头:

    1. NextPage 值调整window.location
    2. 当用户刷新页面时,浏览器会将GET请求协商到NextPage而不是rePOST表单数据

    我认为如果实施这将是极好的,不是吗? =)

    【讨论】:

      【解决方案9】:
      1. 使用标题并重定向页面。

        header("Location:your_page.php");您可以重定向到同一页面或不同页面。

      2. 将 $_POST 插入数据库后取消设置。

        unset($_POST);

      【讨论】:

      • 取消设置 $_POST 根本不会影响表单重新提交,至少在 Chrome 中不会。
      • 这行不通。当用户返回后页时,它会再次执行 POST 变量的设置。
      • 使用unset的原因是什么?请在您的答案中添加一些解释,以便其他人可以从中学习
      【解决方案10】:

      一个非常可靠的方法是在帖子中实现一个唯一的 ID 并将其缓存在

      <input type='hidden' name='post_id' value='".createPassword(64)."'>
      

      然后在您的代码中执行以下操作:

      if( ($_SESSION['post_id'] != $_POST['post_id']) )
      {
          $_SESSION['post_id'] = $_POST['post_id'];
          //do post stuff
      } else {
          //normal display
      }
      
      function createPassword($length)
      {
          $chars = "abcdefghijkmnopqrstuvwxyz023456789";
          srand((double)microtime()*1000000);
          $i = 0;
          $pass = '' ;
      
          while ($i <= ($length - 1)) {
              $num = rand() % 33;
              $tmp = substr($chars, $num, 1);
              $pass = $pass . $tmp;
              $i++;
          }
          return $pass;
      }
      

      【讨论】:

      • 我实际上只是写了类似的东西,但没有麻烦地创建密码,我只是列举了我的表单(例如:步骤 1-5),所以如果它们相等我们很高兴继续前进,否则不要保存到数据库或发送电子邮件。但是让用户随心所欲地降落。
      • 我认为这是比重新加载页面更好的解决方案,因为我在发布成功时会显示​​一条消息,并且重新加载页面会删除该消息。这对我有用,你也可以使用 uniqid
      【解决方案11】:

      使用表单数据后,只需将其重定向到同一页面,就可以了。我试过了。

      header('location:yourpage.php');
      

      【讨论】:

      • 这只是重复其他人多年前给出的相同答案。 (实际上是另外两个!)
      • 如果你重复别人的答案,你至少应该在你的答案中添加一些解释,让它变得有趣
      【解决方案12】:

      Moob 帖子的精炼版。创建 POST 的哈希,将其保存为会话 cookie,然后比较每个会话的哈希。

      // Optionally Disable browser caching on "Back"
      header( 'Cache-Control: no-store, no-cache, must-revalidate' );
      header( 'Expires: Sun, 1 Jan 2000 12:00:00 GMT' );
      header( 'Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT' );
      
      $post_hash = md5( json_encode( $_POST ) );
      
      if( session_start() )
      {
          $post_resubmitted = isset( $_SESSION[ 'post_hash' ] ) && $_SESSION[ 'post_hash' ] == $post_hash;
          $_SESSION[ 'post_hash' ] = $post_hash;
          session_write_close();
      }
      else
      {
          $post_resubmitted = false;
      }
      
      if ( $post_resubmitted ) {
        // POST was resubmitted
      }
      else
      {
        // POST was submitted normally
      }
      

      【讨论】:

        【解决方案13】:

        基本上,您需要重定向到该页面之外,但在您的互联网速度较慢时仍然会出现问题(来自服务器端的重定向标头)

        基本场景示例:

        点击提交按钮两次

        解决方法

        • 客户端

        • 服务器端

          • 在发送请求时使用基于区分的哈希时间戳/时间戳。
          • 用户请求令牌。当主加载时分配一个临时请求令牌,如果重复则忽略。

        【讨论】:

          【解决方案14】:

          如何防止没有重定向的 php 表单重新提交。如果您使用 $_SESSION(在 session_start 之后)和 $_POST 表单,您可以执行以下操作:

          if ( !empty($_SESSION['act']) && !empty($_POST['act']) && $_POST['act'] == $_SESSION['act'] ) {
            // do your stuff, save data into database, etc
          }
          

          在您的 html 表单中输入:

          <input type="hidden" id="act" name="act" value="<?php echo ( empty($_POST['act']) || $_POST['act']==2 )? 1 : 2; ?>">
          <?php
          if ( $_POST['act'] == $_SESSION['act'] ){
              if ( empty( $_SESSION['act'] ) || $_SESSION['act'] == 2 ){
                  $_SESSION['act'] = 1;
              } else {
                  $_SESSION['act'] = 2;
              }
          }
          ?>
          

          因此,每次提交表单时,都会生成一个新的行为,存储在会话中并与发布行为进行比较。

          Ps:如果您使用的是 Get 表单,您可以轻松地使用 GET 更改所有 POST 并且它也可以工作。

          【讨论】:

            【解决方案15】:

            插入数据库后,调用 unset() 方法清除数据。

            未设置($_POST);

            为防止刷新数据插入,请在插入记录后将页面重定向到同一页面或不同页面。

            header('Location:'.$_SERVER['PHP_SELF']);

            【讨论】:

            • 请在您的答案中添加一些解释,以便其他人可以从中学习 - 为什么需要unset 电话?如果你跳过它会发生什么?
            【解决方案16】:

            $_POST['submit'] 变量在页面初始加载时不会存在,只有在以下条件为真时才能运行 curl。

            if($_POST['submit'] == "submit"){
            
            // This is where you run the Curl code and display the output
              $curl = curl_init();
            
            
            
            //clear $post variables after posting
            $_POST = array();
            
            }
            

            【讨论】:

              【解决方案17】:

              使用来自 Keverw 答案的 Post/Redirect/Get 模式是一个好主意。但是,您无法停留在您的页面上(我认为这是您所要求的?)此外,有时可能fail

              如果网络用户在初始提交完成之前刷新 由于服务器滞后,导致重复的 HTTP POST 请求 某些用户代理。

              如果文本应该像这样写入 SQL 数据库,另一种选择是存储在会话中:

              if($_SERVER['REQUEST_METHOD'] != 'POST')
              {
                $_SESSION['writeSQL'] = true;
              }
              else
              {
                if(isset($_SESSION['writeSQL']) && $_SESSION['writeSQL'])
                {
                  $_SESSION['writeSQL'] = false;
              
                  /* save $_POST values into SQL */
                }
              }
              

              【讨论】:

                【解决方案18】:

                正如其他人所说,使用 post/redirect/get 是不可能的。但同时在服务器端做你想做的事情也很容易。

                在您的 POST 页面中,您只需验证用户输入但不对其进行操作,而是将其复制到 SESSION 数组中。然后,您再次重定向回主提交页面。您的主要提交页面首先检查您正在使用的 SESSION 数组是否存在,如果存在,请将其复制到本地数组中并取消设置。从那里你可以采取行动。

                这样你只做一次你所有的主要工作,实现你想做的事情。

                【讨论】:

                  【解决方案19】:

                  我在之后的大型项目中寻找防止重新提交的解决方案。 该代码高度适用于 $_GET 和 $_POST,我无法更改表单元素的行为而不会出现无法预料的错误风险。 所以,这是我的代码:

                  <!-- language: lang-php -->
                  <?php
                  
                  // Very top of your code:
                  
                  // Start session:
                  session_start();
                  
                  // If Post Form Data send and no File Upload
                  if ( empty( $_FILES ) && ! empty( $_POST ) ) {
                      // Store Post Form Data in Session Variable
                      $_SESSION["POST"] = $_POST;
                      // Reload Page if there were no outputs
                      if ( ! headers_sent() ) {
                          // Build URL to reload with GET Parameters
                          // Change https to http if your site has no ssl
                          $location = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
                          // Reload Page
                          header( "location: " . $location, true, 303 );
                          // Stop any further progress
                          die();
                      }
                  }
                  
                  // Rebuilt POST Form Data from Session Variable
                  if ( isset( $_SESSION["POST"] ) ) {
                      $_POST = $_SESSION["POST"];
                      // Tell PHP that POST is sent
                      $_SERVER['REQUEST_METHOD'] = 'POST';
                  }
                  
                  // Your code:
                  ?><html>
                      <head>
                          <title>GET/POST Resubmit</title>
                      </head>
                      <body>
                  
                      <h1>Forms:</h1>
                      <h2>GET Form:</h2>
                      <form action="index.php" method="get">
                          <input type="text" id="text_get" value="test text get" name="text_get"/>
                          <input type="submit" value="submit">
                      </form>
                      <h2>POST Form:</h2>
                      <form action="index.php" method="post">
                          <input type="text" id="text_post" value="test text post" name="text_post"/>
                          <input type="submit" value="submit">
                      </form>
                      <h2>POST Form with GET action:</h2>
                      <form action="index.php?text_get2=getwithpost" method="post">
                          <input type="text" id="text_post2" value="test text get post" name="text_post2"/>
                          <input type="submit" value="submit">
                      </form>
                      <h2>File Upload Form:</h2>
                      <form action="index.php" method="post" enctype="multipart/form-data">
                          <input type="file" id="file" name="file">
                          <input type="submit" value="submit">
                      </form>
                  
                      <h1>Results:</h1>
                      <h2>GET Form Result:</h2>
                      <p>text_get: <?php echo $_GET["text_get"]; ?></p>
                      <h2>POST Form Result:</h2>
                      <p>text_post: <?php echo $_POST["text_post"]; ?></p>
                      <h2>POST Form with GET Result:</h2>
                      <p>text_get2: <?php echo $_GET["text_get2"]; ?></p>
                      <p>text_post2: <?php echo $_POST["text_post2"]; ?></p>
                      <h2>File Upload:</h2>
                      <p>file:
                      <pre><?php if ( ! empty( $_FILES ) ) {
                              echo print_r( $_FILES, true );
                          } ?></pre>
                      </p>
                      <p></p>
                      </body>
                      </html><?php
                  // Very Bottom of your code:
                  // Kill Post Form Data Session Variable, so User can reload the Page without sending post data twice
                  unset( $_SESSION["POST"] );
                  

                  它只能避免重新提交 $_POST,而不是 $_GET。但这是我需要的行为。 重新提交问题不适用于文件上传!

                  【讨论】:

                    【解决方案20】:

                    对我有用的是:

                    if ( !refreshed()) {
                       //Your Submit Here
                            if (isset( $_GET['refresh'])) {
                                setcookie("refresh",$_GET['refresh'], time() + (86400 * 5), "/");
                            }
                    
                        }    
                    }
                    
                    
                    function refreshed()
                    {
                        if (isset($_GET['refresh'])) {
                            $token = $_GET['refresh'];
                            if (isset($_COOKIE['refresh'])) {
                                if ($_COOKIE['refresh'] != $token) {
                                    return false;
                                } else {
                                    return true;
                                }
                            } else {
                                return false;
                            }
                        } else {
                            return false;
                        }
                    }  
                    
                    
                    function createToken($length) {
                        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                        $charactersLength = strlen($characters);
                        $randomString = '';
                        for ($i = 0; $i < $length; $i++) {
                            $randomString .= $characters[rand(0, $charactersLength - 1)];
                        }
                        return $randomString;
                    }
                    
                    ?>
                    

                    在你的表单中

                     <form  action="?refresh=<?php echo createToken(3)?>">
                    
                    
                    
                     </form>
                    

                    【讨论】:

                      【解决方案21】:

                      form.php 示例展示了如何正确使用 PRG(当表单有效或无效时)。

                      • 仅当表单有效并执行操作时才会重定向到同一页面。
                      • 重定向可防止表单在页面刷新时重新提交。
                      • 当表单有效时,它使用会话不会丢失您想要显示的成功消息。
                      • 有两个用于测试的按钮:“有效提交”、“无效提交”。尝试两者并在此之后刷新页面。
                      <?php
                      session_start();
                      
                      function doSelfRedirect()
                      {
                        header('Location:'.$_SERVER['PHP_SELF']);
                        exit;
                      }
                      
                      function setFlashMessage($msg)
                      {
                        $_SESSION['message'] = $msg;
                      }
                      
                      function getFlashMessage()
                      {
                        if (!empty($_SESSION['message'])) {
                          $msg = $_SESSION['message'];
                          unset($_SESSION['message']);
                        } else {
                          $msg = null;
                        }
                      
                        return $msg;
                      }
                      
                      if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                        // Validation primitive example.
                        if (empty($_POST['valid'])) {
                          $formIsValid = false;
                          setFlashMessage('Invalid form submit');
                        } else {
                          $formIsValid = true;
                        }
                      
                        if ($formIsValid) {
                          // Perform any actions here.
                          // ...
                      
                          // Cool!
                          setFlashMessage('Form is valid. Action performed.');
                      
                          // Prevent form resubmission.
                          doSelfRedirect();
                        }
                      }
                      ?>
                      <h1>Hello form</h1>
                      
                      <?php if ($msg = getFlashMessage()): ?>
                        <div><?= $msg ?></div>
                      <?php endif; ?>
                      
                      <form method="post">
                        <input type="text" name="foo" value="bar"><br><br>
                        <button type="submit" name="invalid" value="0">Invalid submit</button>
                        <button type="submit" name="valid" value="1">Valid submit</button>
                      </form>
                      

                      【讨论】:

                        【解决方案22】:
                        if (($_SERVER['REQUEST_METHOD'] == 'POST') and (isset($_SESSION['uniq']))){
                            if($everything_fine){
                                unset($_SESSION['uniq']);
                            }
                        }
                        else{
                            $_SESSION['uniq'] = uniqid();
                        }
                        

                        $everything_fine 是表单验证的布尔结果。如果表单未验证,则通常应再次显示并提示要更正的内容,以便用户可以再次发送。因此,如果需要更正的形式,也会再次创建 $_SESSION['uniq']

                        【讨论】:

                        • 请在您的答案中添加一些解释,以便其他人可以从中学习 - $everything_fine 来自哪里?
                        • @NicoHaase $everything_fine 是表单验证的布尔结果。如果表单未验证,则通常应再次显示并提示要更正的内容,以便用户可以再次发送。因此,如果需要更正的表单,也会再次创建 $_SESSION['uniq']
                        • 请通过编辑在您的答案中添加全部解释
                        • @NicoHaase 这不是我的答案,我所做的描述在答案的代码中很明显。
                        【解决方案23】:

                        为什么不直接使用$_POST['submit'] 变量作为逻辑语句来保存表单中的任何内容。您始终可以重定向到同一页面(如果他们刷新,并且当他们在浏览器中点击go back 时,将不再设置提交帖子变量。只要确保您的提交按钮有一个name 和@987654325 @submit.

                        【讨论】:

                        猜你喜欢
                        • 2020-12-25
                        • 2013-11-06
                        • 2021-07-02
                        • 2016-01-18
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多