在 Laravel 5.1 中使用 VueJs 和 AJAX 提交表单

Posted

技术标签:

【中文标题】在 Laravel 5.1 中使用 VueJs 和 AJAX 提交表单【英文标题】:Submit form using VueJs and AJAX in Laravel 5.1 【发布时间】:2016-10-31 19:35:07 【问题描述】:

我正在尝试使用 AJAX 和 VueJs 提交表单。但不知何故,我未能实现这一目标。我总是得到一个空的Illuminate\Http\Request 对象。

刀片文件:

<body>
    <div class="container">
        <generate-admin></generate-admin>
    </div>

    <script src="https:http://code.jquery.com/jquery.js"></script>
    <script src=" url('/js/main.js') "></script>
</body>

组件:

<template>
    <form id="createAdministrator" @submit.prevent="createAdministrator">

        <div class="form-group">

           <input type="text"
                  name="username"
                  id="txtUserName"
                  placeholder="Username"
                  autocomplete="off"
                  v-model="username"
           />

        </div>

        <input type="submit" value="Submit">

    </form>
</template>

<script>
    export default 
        data: function() 
            return 
                username: ''
            
        ,

        methods: 
            createAdministrator: function() 
                formContents = jQuery("#createAdministrator").serialize();

                this.$http.post('/admin', formContents).then(function(response, status, request) 
                    console.log(response);
                , function() 
                    console.log('failed');
                );
            
        
    
</script>

main.js

import Vue from 'vue';
import GenerateAdmin from './components/GenerateAdmin.vue';

var VueResource = require('vue-resource')
Vue.use(VueResource);

Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('content');
Vue.http.options.emulateJSON = true;

new Vue(
    el: 'body',

    components:  GenerateAdmin 
);

gulpfile.js

var elixir = require('laravel-elixir');

require('laravel-elixir-vueify');

elixir(function(mix) 
    mix.browserify('main.js');
);

routes.php

Route::get('/admin/create', function () 
    return view('admin.create');
);

Route::post('/admin', function(Request $request) 
    // returns an empty object.
    return response(['results' => $request]);
);

Route::get('/', function () 
    return view('welcome');
);

我得到的回报是:

""results":"attributes":,"request":,"query":,"server":,"files":,"cookies":,"headers":"

当我在 Chrome 中检查“网络”选项卡的“请求有效负载”部分时。我确实看到表单已成功提交,无论我在上面的文本框中输入什么数据。

为什么会这样?请指导我在哪里犯了错误?


更新 1:

我正在对上面的代码进行反复试验。我删除了命名空间 Illuminate\Http\Request 并从 post 路由中删除了参数 Request $request。并将传递参数从字符串更改为对象。

这样做,为我完成了我正在寻找的工作。为什么我不知道。我仍在寻找可以向我解释这一点的人。

为什么在 routes.php 文件中添加命名空间 Iluminate\Http\Request 没有像我预期的那样工作,而删除它来完成任务?

谁能告诉我为什么没有早点解决?非常感谢任何形式的帮助。


P.S.:我最近开始学习 VueJs 组件。

【问题讨论】:

我从未尝试过 jQuery().serialize(),相反,我更喜欢在 Vue 组件中设置一个 json 数据对象,然后将该数据对象与 post 请求一起发送。在你的createAdministrator() 中尝试发送this.username 作为请求数据,看看你得到了什么。例如:createAdministrator()this.$http.post('/admin', this.username).then(response =&gt; console.log(response);) @Donkarnash Nope.. 那也没有用.. 同样的事情发生了.. 返回了一个空对象.. 只是预感,没试过。但是 .serialize() 不会返回类似“username=WhateverTheInputIs”的字符串吗?我认为您想要发布一个对象,例如: 'username': WhatTheInputIs 。 【参考方案1】:

作为我遵循的一般做法,任何需要传递给 laravel 控制器的表单数据都作为 json 对象从 vue 前端传递。然后在 laravel 控制器(在您的情况下使用闭包函数路由)中,使用 $request-&gt;get('key') 检索来自接收到的 json 对象的值。 所以在你的情况下,组件代码可能是

    <template>
    <form id="createAdministrator" @submit.prevent="createAdministrator">

        <div class="form-group">

           <input type="text"
                  name="username"
                  id="txtUserName"
                  placeholder="Username"
                  autocomplete="off"
                  v-model="username"
           />

        </div>

        <input type="submit" value="Submit">

    </form>
</template>

<script>
    export default
      template:require('./generate-admin-template.html'),
      data() 
          return 
              username: ''
          
      ,
      computed:
        formData()
          return 
            username:this.username
          
        
      ,
      methods: 
          createAdministrator: function() 
              this.$http.post('/admin', this.formData).then(function(response) 
                  console.log(response);
              , function() 
                  console.log('failed');
              );
          
      
    
</script>

然后在你的routes.php 文件中

<?php
use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/

Route::get('/', function () 
    return view('welcome');
);

Route::get('/admin/create', function () 
    return view('admin.create');
);

Route::post('/admin', function (Request $request) 
    return response(['results' => $request->get('username')]);
);  

我猜Illuminate\Http\Request 实例返回一个$request - Collection,所以我们需要使用Methods available on Collections 访问这些值。 我已经测试了上面的代码以及main.js'/admin/create' 的代码。 还有一件事 - 我认为如果您将序列化的表单数据发送到控制器,那么在控制器内需要对其进行反序列化,以便获取包含 $key=&gt;$value 对的对象或数组,以方便获取所需的数据。

【讨论】:

看来你掌握了 vue.js。我需要你的帮助。看这里:***.com/questions/41843823/…【参考方案2】:

Request 和 SymfonyRequest 类上的所有变量($attributes、$request、$query 等)都受到保护,因为这两个类都没有实现 __toString,php 尽其所能为您提供。

如果需要查看每个值,则需要调用正确的 getter。比如:

Route::post('/admin', function(Request $request)     
    return response(['server' => $request->server(), 'form'=>$request->all()]);
);

【讨论】:

检查您的 JS 代码,在浏览器中查看请求并在此处查看 Laravel 的站点 laravel.com/docs/5.1/requests#retrieving-input

以上是关于在 Laravel 5.1 中使用 VueJs 和 AJAX 提交表单的主要内容,如果未能解决你的问题,请参考以下文章

在 Vue JS 和 Laravel 5.1 + Entrust 中检查特定角色的权限

使用 vuejs 和 laravel 在 URL 中传递参数

形成 laravel 和 vueJS

使用 laravel 后端 api 在 vuejs 中搜索

Laravel 5.1 + Vue.js - vue-router beforeEach AuthService

使用 laravel 和 vuejs 导出 Excel