跨站请求伪造(csrf)是一种常见的网络攻击,攻击者诱导用户执行他们不情愿的操作。laravel框架内置了强大的csrf保护机制,通过生成一个独特的、与用户会话绑定的令牌(token)来防止此类攻击。在每个表单提交或ajax请求中,都需要包含这个csrf令牌,服务器端会验证其有效性。如果令牌不匹配或缺失,请求将被拒绝。
通常,Laravel会将CSRF令牌嵌入到HTML页面的标签中,以便JavaScript可以访问:
<meta name="csrf-token" content="{{ csrf_token() }}">
然后,在AJAX请求中,我们通常会从这个meta标签中获取令牌并将其作为X-CSRF-TOKEN头发送到服务器。
在使用AJAX提交表单时,一个常见的问题是,当用户首次提交表单失败(例如,由于输入验证错误)后,修正信息并再次提交时,会遇到“CSRF token mismatch”错误。尽管第一次提交可能正常工作,但随后的尝试却失败了。
导致此问题的主要原因通常是客户端如何处理和发送CSRF令牌。在原始代码中,CSRF令牌的头部设置是放在$.ajaxSetup中的:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
$.ajaxSetup方法用于为未来的所有AJAX请求设置默认选项。这意味着,当页面加载并执行$.ajaxSetup时,它会从标签中获取当前的CSRF令牌值,并将其缓存起来,作为后续所有AJAX请求的默认X-CSRF-TOKEN头部。
问题在于,如果服务器端在处理某个请求后(即使是失败的请求)更新了会话状态,或者由于某种原因导致原始令牌失效(尽管Laravel默认不会在验证失败后立即更新CSRF令牌),那么$.ajaxSetup中缓存的令牌就可能变得陈旧或无效。由于页面没有重新加载,标签中的内容没有更新,但服务器期望的是一个与当前会话状态匹配的有效令牌。当用户第二次提交时,发送的仍然是$.ajaxSetup中缓存的那个旧令牌,从而导致“CSRF token mismatch”错误。
解决这个问题的关键在于确保每次AJAX请求都获取并发送当前有效的CSRF令牌。最直接有效的方法是,将CSRF令牌的头部设置从$.ajaxSetup中移除,并直接放置在每个需要发送令牌的$.ajax请求配置中。这样,每次发起AJAX请求时,$('meta[name="csrf-token"]').attr('content')都会被重新评估,从而确保获取到的是DOM中当前可用的最新令牌。
修正后的JavaScript代码示例:
$(document).ready(function() { $('#send_form').click(function(e) { e.preventDefault(); // 移除 $.ajaxSetup 中的 CSRF 头部设置 // $.ajaxSetup({ // headers: { // 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') // } // }); $('#send_form').html('Sending..'); /* Submit form data using ajax*/ $.ajax({ url: "{{ route('register')}}", method: 'POST', // 将 CSRF 令牌头部直接包含在当前请求中 headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, data: $('#ajax-register-form').serialize(), success: function(response) { $('#send_form').html('Submit'); document.getElementById("ajax-register-form").reset(); // 可以在此处处理成功响应,例如显示成功消息 }, error: function(data) { var errors = data.responseJSON; console.log(errors); $('.error-warning').show(); // 可以在此处处理错误响应,例如显示错误信息 // 注意:如果服务器在错误响应中返回了新的CSRF令牌, // 并且你需要用它来更新meta标签,则需要在此处额外处理。 // 但通常情况下,只需确保每次请求都从DOM获取当前令牌即可。 } }); }); });
在Laravel中使用AJAX进行表单提交时,为了避免“CSRF token mismatch”错误,尤其是在多次提交尝试中,最佳实践是将CSRF令牌的头部信息直接包含在每个$.ajax请求中,而不是使用$.ajaxSetup进行全局设置。这样可以确保每次请求都能动态获取并发送当前有效的CSRF令牌,从而保证请求的顺利进行,并提供更流畅的用户体验。
以上就是优化Laravel AJAX请求中的CSRF令牌处理以避免不匹配错误的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号