如何通过REST_API在AJAX提交中包含文件附件?

时间:2020-07-18 作者:shanebp

通过jQuery和admin ajax提交表单数据时,包含文件附件很容易:

var data = new FormData($(this)[0]);

在向Rest控制器提交表单数据时,如何包含文件附件?

这将提交除文件附件以外的所有表单字段。

var data = $this.serializeArray();

jQuery:

   $(\'#create-book-form\').submit(function (e) {
    
        var $this = $(this);
        e.preventDefault();
    
        //var data = new FormData($(this)[0]); 
    
        var data = $this.serializeArray(); 
        data.push({name: "rtype", value: "create"});
    
        $.ajax({
    
            url: BOOK_SUBMITTER.root + \'rfp-books/v1/books\',
            data: $.param(data),
            beforeSend: function ( xhr ) {
                xhr.setRequestHeader( \'X-WP-Nonce\', BOOK_SUBMITTER.nonce );
            },
            //etc
除了文件不是到达rest控制器的表单数据的一部分之外,所有这些都可以工作。是的,我有一个名为“file”的输入,因此用户可以包含jpg。

我需要在一次调用中发送所有表单数据。帖子附件在控制器中创建帖子后立即创建。那么,如何将文件放入$.param(data)

在REST控制器中的路由回调中:

$params = $request->get_params();
write_log( $params );
日志显示除文件外的所有表单数据。(如果我将jQuery数据作为FormData提交,那么控制器中不会识别任何数据。)

2 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

你真的可以使用FormData 就像你可以用它和旧的admin-ajax.php 路线,但:

设置processDatacontentTypefalse.

设置methodPOST <确保REST API路由支持POST 方法

$(\'#create-book-form\').submit(function (e) {

//  var $this = $(this); // what\'s this?
    e.preventDefault();

    var data = new FormData( this ); 

    data.append( \'rtype\', \'create\' ); // add extra param

    $.ajax({

        url: BOOK_SUBMITTER.root + \'rfp-books/v1/books\',
        data: data, //$.param(data),
        processData: false,
        contentType: false,
        method: \'POST\',
        beforeSend: function ( xhr ) {
            xhr.setRequestHeader( \'X-WP-Nonce\', BOOK_SUBMITTER.nonce );
        },
        success: function ( data ) {
            console.log( data ); // I added just for testing purposes.
        },
    });
});
然后在REST API端点回调中,只需使用$_FILES 获取上传的文件,例如。$_FILES[\'file\']. 对于其他参数,可以使用$request->get_param(), e、 g。$request->get_param( \'rtype\' ).

此外,对于其他读者,您应该在表单中有一个文件上传输入,例如:。<input type="file" name="file" />, 但是name 可以是任何内容,除非使用默认值创建附件wp/v2/media 路线

SO网友:Ahmad Wael

我使用了这段代码,它在ajax请求中上载文件

<style>
    .wbc_form {
        width: 500px;
        max-width: 100%;
        margin: 0 auto;
        text-align: center;
    }

    .image_preview {
        width: 500px;
        max-width: 100%;
        height: 250px;
        border: 3px dashed #eee;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .image_preview img {
        width: 100%;
        height: auto;
        max-height: 100%;
        display: none;
    }
</style>
<form class="wbc_form" action="<?php echo esc_url( admin_url( \'admin-ajax.php\' ) ) ?>" method="POST"
      enctype="multipart/form-data">
    <h1>
        <?php esc_html_e( \'Upload payment confirmation image\', \'wbc\' ); ?>
    </h1>
    <input type="hidden" name="action" value="wbc_bacs_confirm">
    <?php wp_nonce_field() ?>
    <input type="hidden" name="order_id" id="wbc_order_id" value="<?php echo esc_attr( $order_id ); ?>">
    <input type="file" class="wbc_image" name="wbc_image" value="" accept="image/*">
    <div class="image_preview">
        <img src="" class="img_preview__image" alt="Preview">
        <span class="img_preview__default_text"><?php esc_html_e( \'Image Preview\', \'wbc\' ); ?></span>
    </div>
    <br>
    <button class="go_now button alt" type="submit"><?php esc_html_e( \'Send\', \'wbc\' ); ?></button>
</form>

<script>
    (function ($) {
        let input_file = $(\'.wbc_image\'),
            preview_image = $(\'.img_preview__image\'),
            preview_text = $(\'.img_preview__default_text\');

        input_file.on(\'change\', function (e) {
            let f = this.files[0];

            //here I CHECK if the FILE SIZE is bigger than 2 MB (numbers below are in bytes)
            if (f.size > 2097152 || f.fileSize > 2097152) {
                //show an alert to the user
                alert(wbc_object.max_file_size_msg);
                //reset file upload control
                this.value = null;
            }

            let file = e.target.files[0];
            if (file) {
                let reader = new FileReader();
                preview_text.hide();
                preview_image.show();
                reader.onload = function (event) {
                    preview_image.attr("src", event.target.result)
                };
                reader.readAsDataURL(file);
            } else {
                preview_image.attr(\'src\', \'\');
                preview_image.hide();
                preview_text.show();
            }
        });


        $(\'.wbc_form\').on(\'submit\', function (e) {
            e.preventDefault();
            var formData = new FormData(this);
            $.ajax({
                url: wbc_object.ajax_url,
                type: "POST",
                data: formData,
                contentType: false,
                processData: false,
                success: function (response) {
                    // console.log(response);
                    if (response.success) {
                        $(\'.wbc_form\').html(wbc_object.request_received_msg);
                    } else {
                        //show the toastr js message
                        // toastr.error(response.data.msg);
                    }
                }
            });
        });

    })(jQuery);
</script>
然后您将收到请求参数中的文件