Laravel Vue SPA中如何在Axios请求中使用Blade路由语法?
首先得搞清楚为什么会出现这个奇怪的URL:你的Register.vue是Vue组件,会被Webpack打包成前端资源文件,浏览器运行时根本不认识Laravel的blade语法(比如route()函数)。你写的@{{ route("register") }}会被直接当成字符串发送,自然就变成了编码后的http://127.0.0.1:8000/@%7B%7B%20route(%22register%22)%20%7D%7D,导致404错误。
下面是几个靠谱的解决方法,按推荐程度排序:
方法1:在Blade模板中注入全局路由变量
这是最直接的方式,因为Blade模板是Laravel渲染的,能正确解析route()函数。
在你的resources/views/app.blade.php里,引入app.js之前添加一段脚本,把注册路由地址挂载到全局:
<body> <div id="app"></div> <!-- 添加这段全局变量注入 --> <script> window.Laravel = { registerUrl: "{{ route('register') }}" }; </script> <script src="{{ asset('js/app.js') }}"></script> </body>
然后在Register.vue里直接使用这个全局变量作为请求URL:
axios.post(window.Laravel.registerUrl, { name: this.name }, { headers: { 'Content-type': 'application/json', } }) .then(response => { this.result = response.data.bpi }) .catch(error => { console.log(error) this.errored = true });
注意:我把你原来的
this.name改成了{ name: this.name },因为Axios发送JSON数据时,需要把参数包装成对象,否则后端可能无法正确解析请求体。
方法2:给Vue实例添加全局属性
如果不想直接使用全局变量,可以把路由地址挂载到Vue的全局原型上,这样所有组件都能通过this访问。
先按照方法1在Blade里注入全局变量,然后在app.js里修改:
window.axios = require('axios'); import Vue from 'vue'; // 记得导入Vue import router from './router'; import App from '../components/App.vue'; // 挂载全局属性 Vue.prototype.$apiUrls = { register: window.Laravel.registerUrl }; var app = new Vue({ el: '#app', render: h => h(App), router, mounted(){ // 这里你原来写的是mount,应该是mounted钩子,修正一下 console.log("Root instance mounted "); } });
然后在Register.vue里这样用:
axios.post(this.$apiUrls.register, { name: this.name }, { headers: { 'Content-type': 'application/json', } }) // ... 后续代码不变
方法3:直接使用相对路径(适合简单场景)
如果你的前端和后端在同一个域名下,可以直接写相对路径'/register',前提是Axios的baseURL配置正确。
在app.js里设置Axios的默认baseURL:
window.axios = require('axios'); // 设置baseURL,确保和你的Laravel服务地址一致 axios.defaults.baseURL = 'http://127.0.0.1:8000'; // ... 其他代码
然后在Register.vue里直接用:
axios.post('/register', { name: this.name }, { headers: { 'Content-type': 'application/json', } }) // ... 后续代码不变
另外还要提醒你:Laravel的Auth::routes()已经包含了POST方法的/register路由,所以只要URL正确,后端就能接收到请求。
内容的提问来源于stack exchange,提问作者Istiaque Ahmed

