You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用React JSX替代Laravel Blade邮件模板实现密码重置邮件发送

问题

我正在用Laravel API和React开发忘记密码与重置密码功能,表单部分已经完成,目前卡在后端环节。在forgotPassword函数中,需要向用户邮箱发送密码重置链接,但当前代码Mail::send('email.forgetPassword',)调用的是Laravel的Blade视图文件。我是第一次用Laravel做认证,请问该如何调整这部分来使用React的JSX?

后端函数代码

public function forgotPassword(Request $request){
        $request->validate(['email' => ['required', 'string', 'email', 'max:255']]);

        $token = Str::random(64);

        DB::table('password_reset_tokens')->insert([
            'email' => $request->email,
            'token' => $token,
            'created_at' => Carbon::now()
        ]);

        Mail::send('email.forgetPassword', ['token' => $token], 
            function($message) use ($request){
                $message->to($request->email);
                $message->subject('Reset Password');
            }
        );

        return response()->json(['message', 'We have e-mailed your password reset link!']);
    }

路由代码

Route::post('forgot-password', [UserController::class, 'forgotPassword'])->name('password.email');

前端忘记密码表单代码

const handleSubmit = async (event) => {
    event.preventDefault();
    setLoading(true);
    setStatus(null);

    const data = {email};
 
    try {
      await API.get("/api/csrf-cookie").then(async () => {            
        const response = await API.post('/api/forgot-password', data); 
        setStatus(response.data.status);
        if (response.data.error){
          console.log(response.data.error);
          setLoading(false);             
        }
      });          
    } catch (error){
      console.log(error);
      setLoading(false);
    }
}
解决方案

Laravel的Mail类无法直接渲染React JSX(JSX需要React环境编译),这里提供两种可行方案,优先推荐新手友好的第一种:

方案1:将React JSX编译为静态HTML后使用

步骤1:编写React邮件模板并导出为HTML

在你的React项目中创建邮件模板组件,比如PasswordResetEmail.jsx:

export const PasswordResetEmail = ({ token }) => {
  const resetUrl = `https://你的前端域名/reset-password?token=${token}`;
  return (
    <div style={{ fontFamily: 'Arial, sans-serif', padding: '20px' }}>
      <h2>重置你的密码</h2>
      <p>请点击下方链接重置密码:</p>
      <a 
        href={resetUrl} 
        style={{ 
          background: '#007bff', 
          color: 'white', 
          padding: '10px 20px', 
          textDecoration: 'none', 
          borderRadius: '4px' 
        }}
      >
        重置密码
      </a>
      <p>若此请求非你发起,请忽略本邮件。</p>
    </div>
  );
};

你可以通过以下方式获取编译后的HTML:

  • 在浏览器中渲染该组件,右键查看页面源码并复制对应HTML
  • 使用ReactDOMServer.renderToString在Node环境生成HTML字符串

将得到的HTML保存到Laravel项目的resources/views/email/reset-password.html文件中,注意把链接里的${token}替换成占位符(比如{{token}}),方便后续动态替换。

步骤2:修改Laravel后端代码加载静态HTML

把原来调用Blade视图的代码改成读取静态HTML并替换token:

public function forgotPassword(Request $request){
    $request->validate(['email' => ['required', 'string', 'email', 'max:255']]);

    $token = Str::random(64);

    DB::table('password_reset_tokens')->insert([
        'email' => $request->email,
        'token' => $token,
        'created_at' => Carbon::now()
    ]);

    // 读取静态HTML文件
    $html = file_get_contents(resource_path('views/email/reset-password.html'));
    // 替换HTML中的token占位符
    $html = str_replace('{{token}}', $token, $html);

    // 发送HTML邮件
    Mail::send([], [], function($message) use ($request, $html){
        $message->to($request->email)
                ->subject('重置密码')
                ->html($html);
    });

    return response()->json(['message' => '密码重置链接已发送至你的邮箱!']);
}

方案2:通过Node服务端渲染(SSR)生成HTML(进阶)

如果需要频繁修改邮件模板且不想手动复制HTML,可以搭建一个简单的Node服务,用ReactDOMServer.renderToString将JSX编译为HTML,然后Laravel通过HTTP请求获取该HTML后发送邮件。这种方式适合有Node开发基础的开发者,步骤相对繁琐,这里不展开细节。

额外注意事项

  • 确保重置链接指向你的React前端页面,前端需要接收token参数,并在重置密码表单中把token、新密码一起提交给Laravel的重置密码接口
  • 别忘了实现Laravel端的重置密码接口,验证token有效性后更新用户密码并删除对应的重置记录

内容的提问来源于stack exchange,提问作者nur najihah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:14:51