Как передать значение маркера CRAF laravel для vue

У меня есть эта форма, где пользователь должен вводить текст только внутри текстовой области:

            <form action="#" v-on:submit="postStatus">{{-- Name of the method in Vue.js --}}
                <div class="form-group">
                    <textarea class="form-control" rows="5" maxlength="140" autofocus placeholder="What are you upto?" required v-model="post"></textarea>
                </div>
                <input type="submit" value="Post" class="form-control btn btn-info">

                {{ csrf_field() }}

            </form>

Затем у меня есть этот script код, где я использую vue.js с ajax, чтобы передать этот текст в контроллер и в конечном итоге сохранить его в базе данных:

//when we actually submit the form, we want to catch the action
    new Vue({
        el      : '#timeline',
        data    :   {
            post    : '',
        },
        http    :   {
            headers: {
                'X-CSRF-Token': $('meta[name=_token]').attr('content')
            }
        },
        methods : {
            postStatus : function (e) {
                e.preventDefault();
                console.log('Posted: '+this.post+ '. Token: '+this.token);
                $.ajax({
                    url         :   '/posts',
                    type        :   'post',
                    dataType    :   'json',
                    data        :   {
                        'body'  :   this.post,
                    }
                });
            }
        },
    });

Однако это пока не работает, поскольку это исключение несоответствия токенов. Я не знаю, как заставить его работать. Как передать это значение токена контроллеру. Я пробовал следующее:

1) внутри формы, я добавил в токен имя vue:

<input type="hidden" name="_token" value="YzXAnwBñC7qPK9kg7MGGIUzznEOCi2dTnG9h9çpB" v-model="token">

2) Я попытался передать это значение токена в vue:

//when we actually submit the form, we want to catch the action
    new Vue({
        el      : '#timeline',
        data    :   {
            post    : '',
            token   : '',
        },
        methods : {
            postStatus : function (e) {
                e.preventDefault();
                console.log('Posted: '+this.post+ '. Token: '+this.token);
                $.ajax({
                    url         :   '/posts',
                    type        :   'post',
                    dataType    :   'json',
                    data        :   {
                        'body'  :   this.post,
                        '_token':   this.token,
                    }
                });
            }
        },
    });

... но в консоли vue даже не поймает его: (

Это приводит меня к следующей ошибке:

TokenMismatchException в строке VerifyCsrfToken.php 68:

Как это исправить? Любые идеи?

Ответ 1

Просто я бы предложил поместить это в ваш PHP файл:

<script>
    window.Laravel = <?php echo json_encode(['csrfToken' => csrf_token()]); ?>
</script>

Таким образом, вы можете легко импортировать свой csrfToken из части JS (в этом случае Vue).

Кроме того, если вы вставляете этот код в свой файл макета PHP, вы можете использовать токен любым компонентом своего приложения, так как window является глобальной переменной JS.

Источник: я получил трюк этот пост.

Ответ 2

Мое решение заключается в том, что все компоненты vue получают токен csrf перед запросом. Я поместил это в свой файл bootstrap.js.

Vue.http.interceptors.push((request, next) => {
   request.headers.set('X-CSRF-TOKEN', CoolApp.csrfToken);
   next();
});

Затем получим класс CoolApp.php

    public function getScriptVariables()
    {
      return json_encode([
          'csrfToken' => csrf_token(),
      ]);
    }

Ответ 3

Я решил это благодаря этим двум ответам:

1) Сначала я прочитал этот, который привел меня к

2) Этот второй.

Итак, в моей форме я сохраняю это:

{{ csrf_field() }}

И внутри js файла я добавляю только следующее (вне и выше экземпляра Vue):

var csrf_token = $('meta[name="csrf-token"]').attr('content');

Таким образом, весь js-код:

var csrf_token = $('meta[name="csrf-token"]').attr('content');
    /*Event handling within vue*/
    //when we actually submit the form, we want to catch the action
    new Vue({
        el      : '#timeline',
        data    :   {
            post    : '',
            token   : csrf_token,
        },
        methods : {
            postStatus : function (e) {
                e.preventDefault();
                console.log('Posted: '+this.post+ '. Token: '+this.token);
                $.ajax({
                    url         :   '/posts',
                    type        :   'post',
                    dataType    :   'json',
                    data        :   {
                        'body'  :   this.post,
                        '_token':   this.token,
                    }
                });
            }
        },
    });

Ответ 4

Very Easy Solution Просто добавьте скрытое поле внутри формы. Пример

<form id="logout-form" action="/logout" method="POST" style="display: none;">
    <input type="hidden" name="_token" :value="csrf">
</form>

Теперь добавьте переменную csrf внутри script в файле vue, например. (Помните, что это должно быть внутри данных).

<script>
     export default {
        data: () => ({
            csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
          }),        
    }
</script>

N.B. В вашем файле blade.php вы увидите метатег, подобный этому.

<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">

Если нет ничего подобного, вам нужно разместить его там.