窝最近在写一个注册的页面,需要邮箱验证的。窝的思路是这样的:
- 按下发送按钮,就用
AJAX
(原生的)请求PHP
发送验证码。 -
PHP
(参数op=send_ve
) 生成验证码,存到$_SESSION
里面,然后把验证码发到用户邮箱。 - 提交表单之后,
PHP
(同一个文件,参数op=submit
)比对验证码字段的内容和$_SESSION
里面的,不一样就输出 “验证码错误!”
窝试了一下然后很尴尬的 “验证码错误” 了。然后在朋友的建议下试过各种方法:
- 把
session_start();
放到页面最开始。 - 用了一个固定的键名:
"ve"
(本来是用邮箱做) -
测试是不是所有的
$_SESSION
都不能用:- 于是我在发送验证码的地方加了一句
$_SESSION["OK"] = "OK";
- 打印错误信息(“验证码错误”)的地方输出
$_SESSION
。 - 啥也没输出,就一个空的
<p></p>
- 于是我在发送验证码的地方加了一句
代码如下:
- 前端
HTML
,那个链接就是了。 -
后端
PHP
:<?php session_start(); ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html" charset="UTF-8"/> <title>Mushouse - Sign up</title> <link rel="stylesheet" type="text/css" href="https://icelava.ga/style.css"> <link rel="stylesheet" type="text/css" href="https://icelava.ga/fa/css/font-awesome.min.css"> <script type="text/javascript" src="https://icelava.ga/main.js"></script> <script type="text/javascript" src="https://icelava.ga/marked.min.js"></script> <script type="text/javascript" async src="https://cdn.bootcss.com/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> </head> <body onload="init();"> <div id="guide"></div> <p id="pos">Sign up</p> <div id="main"> <div> <p class="title"> <i class="fa fa-sign-in"></i> 注册信息 </p> <?php function echo_text($text) { echo "<p class='text'>" . $text . "</p>"; } function die_text($text) { die("<p class='text'>" . $text . "</p>"); } function qm_str($str) { return "\"" . $str . "\""; } error_reporting(E_ALL); header("Content-Type: text/html; charset=utf-8"); header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: Content-Type,Content-Length,Accept-Encoding,X-Requested-with, Origin"); use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; require "./PHPMailer/src/Exception.php"; require "./PHPMailer/src/PHPMailer.php"; require "./PHPMailer/src/SMTP.php"; try { if ($_GET["op"] == "send_ve") { $ve = ""; for ($i = 0; $i < 6; $i++) $ve .= mt_rand(0, 9); $_SESSION["ve"] = $ve; # Test: $_SESSION["OK"] = "OK"; # Note: 开始发送邮件! $mail = new PHPMailer(true); $mail->CharSet = "UTF-8"; $mail->SMTPDebug = 0; $mail->isSMTP(); $mail->Host = "smtp.qq.com"; $mail->SMTPAuth = true; $mail->Username = "fork_killet@qq.com"; $mail->Password = "xxxx"; $mail->SMTPSecure = "ssl"; $mail->Port = 465; $mail->setFrom("fork_killet@qq.com", "IceLava 团队"); echo $_POST["email"]; $mail->addAddress($_POST["email"], $_POST["email"]); $mail->isHTML(true); $mail->Subject = "Mushouse 注册验证码"; $mail->Body = "<b>这是 IceLava 团队向您发来的验证邮件,<br>如果不是您本人在注册 Mushouse 账户,请不要理睬!</b> <br>"; $mail->Body .= "<p>6 位数字验证码:" . $ve . ",请在注册页面填写。</p> <br>"; $mail->Body .= "<p>-- IceLava 团队</p>"; $mail->AltBody = "很抱歉,您的邮箱太屑了,不支持 HTML 邮件内容!"; $mail->send(); } else if ($_GET["op"] == "submit") { if ($_POST["pw"] != $_POST["pw2"]) echo_text("两次密码输入不一致!"); else if (preg_match("/[^A-Za-z0-9_]/", $_POST["pw"])) echo_text("密码不能包含数字、大小写字母和下划线以外的字符!"); else if (strlen($_POST["pw"]) < 6) echo_text("密码长度必须大于 6!"); else if (strlen($_POST["pw"]) > 16) echo_text("密码长度必须小于 16!"); else if (preg_match("/[^A-Za-z0-9_]/", $_POST["un"])) echo_text("用户名不能包含数字、大小写字母和下划线以外的字符!"); else if (strlen($_POST["un"]) < 4) echo_text("用户名长度必须大于 4!"); else if (strlen($_POST["un"]) > 16) echo_text("用户名长度必须小于 16!"); else if (!preg_match("/^([A-Za-z0-9_\.\-])+\@(([A-Za-z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/", $_POST["email"])) echo_text("邮箱格式不正确!"); # Note: 验证码检查 else if ($_POST["ve"] != $_SESSION["ve"]) { echo_text($_SESSION["ve"]); echo_text("验证码不正确!"); } else { $conn = new mysqli("xxx", "xxx", "xxx", "icelavag"); if ($conn->connect_error) die_text("数据库连接失败: " . $conn->connect_error); $rst = $conn->query ( "SELECT * FROM user_info WHERE un=" . qm_str($_POST["un"]) ); if ($rst->num_rows == 1) echo_text("用户名 " . $_POST["un"] . " 已被注册!"); else { $conn->query ( "INSERT INTO user_info (un, pw, email) VALUES (" . qm_str($_POST["un"]) . ", " . qm_str($_POST["pw"]) . ", " . qm_str($_POST["email"]) . ")" ); echo_text("注册成功!您可以去登陆了," . $_POST["un"] . " ~"); echo_text($_SESSION["OK"]); } } } } catch(\Exception $err) { echo_text($err->getMessage()); } ?> </div> </div> </body> </html>
我调试了两天终于找到了答案,似乎是
BOM
的原因(喷血)但是各个工具都没能解决这个问题,说是没有
BOM
然后我自己手打了一遍就好了……