jQuery CSRF не работает - ForbiddenError: неверный токен csrf

Начиная с Safari 5 / Firefox 4, проще всего использовать класс FormData:

var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
    data.append('file-'+i, file);
});

Итак, теперь у вас есть объект FormData, готовый к отправке вместе с XMLHttpRequest.

jQuery.ajax({
    url: 'php/upload.php',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    method: 'POST',
    type: 'POST', // For jQuery < 1.9
    success: function(data){
        alert(data);
    }
});

Обязательно установить параметр contentType на false, заставляя jQuery не добавлять к вам заголовок Content-Type, иначе пограничная строка будет отсутствовать. Кроме того, вы должны оставить флаг processData установленным как false, в противном случае jQuery попытается преобразовать ваш FormData в строку, которая потерпит неудачу.

Теперь вы можете получить файл на PHP, используя:

$_FILES['file-0']

(Существует только один файл, file-0, если вы не указали атрибут multiple на входе файла, и в этом случае числа будут увеличиваться с каждым файлом.)

Использование эмуляции FormData для старых браузеров

var opts = {
    url: 'php/upload.php',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    method: 'POST',
    type: 'POST', // For jQuery < 1.9
    success: function(data){
        alert(data);
    }
};
if(data.fake) {
    // Make sure no text encoding stuff is done by xhr
    opts.xhr = function() { var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary; return xhr; }
    opts.contentType = "multipart/form-data; boundary="+data.boundary;
    opts.data = data.toString();
}
jQuery.ajax(opts);

Создание FormData из существующей формы

Вместо ручного итерации файлов FormData объект также может быть создан с содержимым существующего объекта формы:

var data = new FormData(jQuery('form')[0]);

Использовать собственный массив PHP вместо счетчика

Просто назовите ваши файловые элементы одинаковыми и запустите имя в скобках:

jQuery.each(jQuery('#file')[0].files, function(i, file) {
    data.append('file[]', file);
});

$_FILES['file'] будет массивом, содержащим поля для загрузки файлов для каждого загруженного файла. Я действительно рекомендую это по сравнению с моим первоначальным решением, поскольку его проще перебирать.

0
задан cphill 27 March 2019 в 11:50
поделиться