Laravel: автоматически отправлять токен CSRF с запросами в vanilla JS

Я использую пакет, установленный с Composer в моем проекте Laravel. Он содержит некоторый код JS для загрузки файлов. По крайней мере в одном случае загрузка не удалась, потому что с запросом не был отправлен токен CSRF.

Надеюсь решить эту проблему без редактирования кода вендора. Это соответствующий JS:

self.upload = function (file, filename) {
  var formData = new FormData();
  formData.append('file', file, filename);
  formData.append('field', JSON.stringify(field));
  formData.append('contentId', H5PEditor.contentId || 0);

  // Submit the form
  var request = new XMLHttpRequest();
  request.upload.onprogress = function (e) {
    if (e.lengthComputable) {
      self.trigger('uploadProgress', (e.loaded / e.total));
    }
  };

  // ...

}

Есть ли способ заставить Laravel автоматически отправлять токен CSRF с таким запросом?

С Axios я бы сделал

window.axios.defaults.headers.common = {
    'X-CSRF-TOKEN': window.Laravel.csrfToken,
    'X-Requested-With': 'XMLHttpRequest'
};

С jQuery я бы сделал

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

Но в моем случае такая библиотека не используется.


person Pida    schedule 10.08.2020    source источник
comment
Я не понимаю, почему вы не используете axios или $.ajax, но ответ здесь может вам помочь.   -  person TKoL    schedule 10.08.2020
comment
Спасибо, я проверю это. Приведенный выше код установлен как зависимость от Composer, поэтому я не хотел бы его менять.   -  person Pida    schedule 10.08.2020
comment
О, я вижу. Да, ответ, на который я ссылался, может быть не совсем рекомендован, но я не думаю, что есть другой способ установить заголовки по умолчанию с помощью XMLHttpRequest, поэтому вам, возможно, придется это сделать.   -  person TKoL    schedule 10.08.2020
comment
У вас есть идеи, где разместить код из другого вопроса в приложении Laravel? Я использовал его в bootstrap.js, затем сделал npm run dev, но пока не успел добавить заголовки...   -  person Pida    schedule 10.08.2020
comment
Просто попробуйте сначала запустить его, пока ваша страница работает в режиме реального времени, в консоли Chrome. Затем сделайте что-нибудь, что вызовет выполнение запроса, и проверьте на вкладке сети, был ли добавлен заголовок. Это был бы первый шаг.   -  person TKoL    schedule 10.08.2020
comment
Это не работает в консоли (или в любом другом файле). Вы бы искали дополнительный заголовок в Заголовки / Заголовки запросов, верно?   -  person Pida    schedule 11.08.2020
comment
Да, вот куда бы вы посмотрели. Ответ переопределяет метод open, но код, который вы вызываете, может фактически не использовать метод open.   -  person TKoL    schedule 11.08.2020
comment
Он использует этот метод. Инкапсуляция кода, кажется, играет роль в моей проблеме. Я объясняю это в другом вопросе: stackoverflow.com/questions/63354643   -  person Pida    schedule 11.08.2020


Ответы (1)


Тебе нужно иметь

<meta name="csrf-token" content="{{ csrf_token() }}" />

на вашей странице

а затем в своем коде вы можете использовать селектор запросов

document.querySelector('meta[name="csrf-token"]')['content']

чтобы получить значение, используйте API-интерфейс fetch, чтобы вы могли добавить заголовок.

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Headers

person Menawer    schedule 10.08.2020
comment
Этого недостаточно. В вашем ответе показано, как отправить токен на HTML-страницу, но мой вопрос заключается в том, как отправить его обратно на сервер в запросе AJAX: laravel.com/docs/7.x/csrf#csrf-x-csrf-token - person Pida; 10.08.2020