Отправить форму с помощью VueJs и AJAX в Laravel 5.1

Я пытаюсь отправить форму, используя 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, а также удалил аргумент Request $request из маршрута post. И изменил передаваемый параметр на объект из строки.

Сделав это, сделал для меня работу, которую я искал. Почему я не знаю. Я все еще ищу кого-то, кто может объяснить это мне.

Почему добавление пространства имен Iluminate\Http\Request в файл routes.php не сработало, как я ожидал, и его удаление выполнило задачу?

Кто-нибудь может сказать мне, почему это не сработало раньше? Любая помощь высоко ценится.


P.S. Недавно я начал изучать компоненты VueJs.


person Saiyan Prince    schedule 29.06.2016    source источник
comment
Я никогда не пробовал jQuery().serialize(), вместо этого я предпочитаю устанавливать объект данных json в компоненте Vue, а затем отправлять этот объект данных с почтовым запросом. В своем createAdministrator() попробуйте отправить this.username в качестве данных запроса и посмотрите, что вы получите. например: createAdministrator(){this.$http.post('/admin', this.username).then(response => {console.log(response);})   -  person Donkarnash    schedule 29.06.2016
comment
@Donkarnash Нет.. Это тоже не сработало.. Произошло то же самое.. Возвратил пустой объект..   -  person Saiyan Prince    schedule 30.06.2016
comment
Просто предчувствие, не пробовал. Но разве .serialize() не возвращает строку вроде: username=WhateverTheInputIs? Я думаю, что вы хотите опубликовать объект, например: { 'username': WhateverTheInputIs}.   -  person Liren    schedule 30.06.2016


Ответы (2)


Я придерживаюсь общей практики: любые данные формы, которые необходимо передать контроллеру laravel, передаются как объект json из интерфейса vue. Затем в контроллере laravel (маршрут с функцией закрытия в вашем случае) значения из полученного объекта json извлекаются с помощью $request->get('key').
Таким образом, в вашем случае код компонента может быть

    <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=>$value пар, для облегчения выборки необходимых данных.

person Donkarnash    schedule 01.07.2016
comment
Кажется, вы осваиваете vue.js. Мне нужна ваша помощь. Посмотрите здесь: stackoverflow .com/questions/41843823/ - person moses toh; 25.01.2017

Все переменные ($attributes, $request, $query и т.д.) в классах Request и SymfonyRequest защищены, поскольку ни один из классов не реализует __toString, php делает все возможное, чтобы дать вам то, что может.

Если вам нужно увидеть каждое значение, вам нужно вызвать правильный геттер. Что-то типа:

Route::post('/admin', function(Request $request) {    
    return response(['server' => $request->server(), 'form'=>$request->all()]);
});
person Mikhail Kozlov    schedule 29.06.2016
comment
Проверьте свой код JS, просмотрите запросы в браузере и проверьте сайт Laravel здесь laravel.com/docs/ 5.1/requests#retrieving-input - person Mikhail Kozlov; 30.06.2016