在JavaScript中通过Fetch API处理CSRF Token
问题解答:Fetch API发送CSRF Token到Laravel后端
1. 能不能用Fetch API实现?
完全可以,Fetch API是原生JS的网络请求API,无需依赖jQuery等库就能实现CSRF Token的传递。
2. Laravel后端需要的HTML配置
Laravel的CSRF验证依赖页面中的有效Token,有两种常用配置方式:
- 若使用Laravel Blade模板,直接在表单内添加
@csrf指令,它会自动生成一个隐藏的_token输入框:<form id="form1"> @csrf <!-- 你的其他表单字段 --> </form> - 若为纯HTML文件,在页面
<head>中添加meta标签输出Token:
(注:<meta name="csrf-token" content="{{ csrf_token() }}">{{ csrf_token() }}是Laravel Blade语法,会渲染为当前有效的CSRF Token值)
3. 你的代码导致419错误的原因
419是Laravel的CSRF验证失败提示,你的代码存在两个核心问题:
- Content-Type与请求体格式不匹配:你设置了
"Content-Type": "application/json",但请求体用的是URLSearchParams(对应application/x-www-form-urlencoded格式),格式冲突导致Laravel无法正确解析请求,进而Token验证失败。 my_token未正确获取:你未明确my_token的来源,必须从页面的meta标签或表单隐藏字段获取有效的Token值。
4. 正确的Fetch API写法
以下提供三种可行写法,按需选择:
写法一:直接用FormData(最简单,推荐表单场景)
利用@csrf生成的隐藏字段,FormData会自动包含_token,无需手动处理请求头:
const form1 = document.getElementById('form1'); const f1_search_url = '/your-api-url'; // 替换为你的后端接口地址 form1.addEventListener('submit', (e) => { e.preventDefault(); const formData = new FormData(form1); fetch(f1_search_url, { method: 'POST', body: formData }) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err)); });
写法二:通过请求头传递Token(适合非表单JSON请求)
从meta标签获取Token,放在请求头中,同时匹配正确的Content-Type:
const form1 = document.getElementById('form1'); const f1_search_url = '/your-api-url'; form1.addEventListener('submit', (e) => { e.preventDefault(); // 从meta标签获取Token const csrfToken = document.querySelector('meta[name="csrf-token"]').content; // 把表单数据转成URL编码格式 const formData = new FormData(form1); const urlEncodedData = new URLSearchParams(formData); fetch(f1_search_url, { method: 'POST', headers: { "X-CSRF-Token": csrfToken, "Content-Type": "application/x-www-form-urlencoded" }, body: urlEncodedData }) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err)); });
写法三:发送JSON格式请求
若需要发送JSON格式数据,需将表单数据转为JSON字符串,同时传递Token:
const form1 = document.getElementById('form1'); const f1_search_url = '/your-api-url'; form1.addEventListener('submit', (e) => { e.preventDefault(); const csrfToken = document.querySelector('meta[name="csrf-token"]').content; const formData = new FormData(form1); // 把FormData转为普通对象再转为JSON字符串 const dataObj = Object.fromEntries(formData); const jsonData = JSON.stringify(dataObj); fetch(f1_search_url, { method: 'POST', headers: { "X-CSRF-Token": csrfToken, "Content-Type": "application/json" }, body: jsonData }) .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err)); });
补充说明
Laravel的CSRF验证会自动检查两种位置的Token:
- 请求头中的
X-CSRF-TOKEN - 请求体中的
_token字段
以上写法均能通过验证,选择最适配你业务场景的即可。
内容的提问来源于stack exchange,提问作者Azizbek Nayimov
相关产品推荐
相关产品推荐

