web-dev-qa-db-ja.com

Wordpress-FormDataを渡すことができません)でのAjaxファイルのアップロード

$ .ajaxとFormDataを使用して2つのフォームオブジェクトをPHPに渡すスクリプトを作成しました。 1つのフォームオブジェクトはテキストで、もう1つはファイルです。スタンドアロンスクリプトとしてうまく機能しました。ただし、Wordpressにプラグインとして追加した後も、"Uncaught TypeError: Illegal invocation"

フォームデータをシリアル化する余裕はありません。PHPのコールバック関数にファイルを渡すことができないからです。

Ajax呼び出しの前にFormDataを含むJS:

var fd = new FormData();
var file = jQuery(this).find('input[type="file"]');
var caption = jQuery(this).find('input[name=img_caption]');
var individual_file = file[0].files[0];
fd.append("file", individual_file);
var individual_capt = caption.val();
fd.append("caption", individual_capt);

上記のこの部分は100%正しいです。

Ajax呼び出し:

jQuery.ajax({
    type: 'POST',
    url: fiuajax.ajaxurl,
    data: {
        action: 'fiu_upload_file',
        security: fiuajax.security,
        data: fd,
        contentType: false,
        processData: false,
    },
    success: function(response){
        var dataObj = jQuery.parseJSON(response);
        if(dataObj.message == 'error') {
            jQuery('.fiu_validation').html('The following error occured: '+dataObj.desc);
        }
        else if(dataObj.message == 'success') {
            jQuery('.fiu_file').val('');
        }
        console.log(response);
    }
});

Wordpressの外では完全に正常に機能したため、これは非常に苛立たしいことです。 WordpressのjQueryの登録を解除し、最新のjQueryバージョンをキューに入れようとしましたが、違いはありませんでした。

要点をまとめると:
1)Ajax/jQueryはフォームオブジェクトをPHPに渡すことを拒否しています
2)ファイルオブジェクトを保持する必要があるため、オブジェクトをシリアル化できません
3)スクリプトはWordpressの外部で機能します
4)最新のjQueryバージョンに更新しようとしましたが、変更はありません

10
Stefan

これを試して :

jQuery(document).on('click', '#submit', function(e){
    e.preventDefault();

    var fd = new FormData();
    var file = jQuery(document).find('input[type="file"]');
    var caption = jQuery(this).find('input[name=img_caption]');
    var individual_file = file[0].files[0];
    fd.append("file", individual_file);
    var individual_capt = caption.val();
    fd.append("caption", individual_capt);  
    fd.append('action', 'fiu_upload_file');  

    jQuery.ajax({
        type: 'POST',
        url: fiuajax.ajaxurl,
        data: fd,
        contentType: false,
        processData: false,
        success: function(response){

            console.log(response);
        }
    });
});

php

function fiu_upload_file(){

    var_dump($_FILES);
    exit();
}

add_action('wp_ajax_fiu_upload_file', 'fiu_upload_file');
add_action('wp_ajax_nopriv_fiu_upload_file', 'fiu_upload_file');
31
David

私はなんとかそれをすることができました。コードはWordpress(4.9.4)の最新バージョンで動作します

まず、jQuery ajaxではなく、XMLHttpRequestを使用してデータを送信しています。これは、純粋なJSだけに適応できることを意味します。このメソッドを使用してFormDataを渡すために不可欠なxhttp.setRequestHeader("enctype","multipart/form-data");に注意してください。

JS:

var user_id = $('#user_id').val();
var picture = $('#userPic')[0].files[0];

console.log(picture);

if( picture && typeof picture !== undefined ) {

  if ( picture['size'] > 1000000 ) {
    alert('The Profile Pic can\'t be larger than 1Mb.');
    return;
  }

  if ( picture['type'].indexOf('image') == -1 ) {
    alert('The uploaded file needs to be an image.');
    return;
  }

  var data = new FormData();
  data.append('user_id', user_id);
  data.append('userPic', picture);

  // console.log(data);

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      console.log('Receive:' + this.responseText);
    }
  };
  xhttp.open("POST", location.Origin + "/wp-content/themes/search-and-go-child/ajax/upload_user_profile_pic_ajax.php", true);
    xhttp.setRequestHeader("enctype","multipart/form-data");
  xhttp.send(data);

}

PHPの部分は、受信したデータをWPコア関数で操作するために必要なファイルが必要なため、非常に便利です。ここには、次のコードもあります。 WPコア関数を使用して添付ファイルをアップロードします。

PHP:

    // error_reporting(-1);
    // ini_set('display_errors', 'On');
    $path = $_SERVER['DOCUMENT_ROOT'];
    require_once($path.'/wp-load.php');
    require_once( '/home/s24t06b21lk5/public_html/wp-includes/template-loader.php' );
    // require_once("/home/s24t06b21lk5/public_html/wp-admin" . '/includes/image.php');
    require_once("/home/s24t06b21lk5/public_html/wp-admin" . '/includes/file.php');
    // require_once("/home/s24t06b21lk5/public_html/wp-admin" . '/includes/media.php');


    $user_id = $_POST['user_id'];
    $picture = $_FILES['userPic'];


    var_dump($user_id);
    var_dump($picture);

    $response = array();

    if( isset($picture['name']) && $picture['name'] ) {

        // Get the path to the upload directory.
        $wp_upload_dir = wp_upload_dir();           

        $picture['name'] = preg_replace( '/[^0-9a-zA-Z.]/', '', basename( $picture['name'] ) );

        // Upload the file
        $upload_overrides = array( 'test_form' => false );
        $upload_result = wp_handle_upload($picture, $upload_overrides);
        // echo '<pre>'; print_r($upload_result); echo '</pre>' ;

        if( $upload_result['url'] ) {

            // Prepare an array of post data for the attachment.
            $attachment = array(
                'guid'           => $upload_result['url'], 
                'post_mime_type' => $picture['type'],
                'post_title'     => $picture['name'],
                'post_content'   => '',
                'post_status'    => 'inherit'
            );


            $attach_id = wp_insert_attachment( $attachment, $upload_result['file'] );

            if( $attach_id ) {

                // Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
                require_once( ABSPATH . 'wp-admin/includes/image.php' );

                // Generate the metadata for the attachment, and update the database record.
                $attach_data = wp_generate_attachment_metadata( $attach_id, $upload_result['file'] );
                wp_update_attachment_metadata( $attach_id, $attach_data );

                // Update the usermeta table with the uploaded avatar
                if( !update_user_meta($user_id, 'wp_user_avatar', $attach_id ) || !update_user_meta($user_id, 'wp_zfgrf5v7rw_user_avatar', $attach_id) ) {
                    $response['result'] = FALSE;
                    $response['message'] = "The uploaded image could not be associated with the User ID in the database.";              
                }
                else {
                    $response['result'] = TRUE;             
                }


            }
            else {
                $response['result'] = FALSE;
                $response['message'] = "Wordpress attachment post for the user's image could not created.";
            }

        }
        else {
            $response['result'] = FALSE;
            $response['message'] = "The file couldn't be uploaded. Check the permissions.";
        }

    }

    die( json_encode($response) );

ありがとうございました。

1
TheoPlatica

追加した

 dataType: 'json'

そしてそれは役立ちます。 Ajax呼び出しのコードの完全なリスト:

jQuery.ajax({
    type: 'POST',
    url: fiuajax.ajaxurl,
    data: {
        action: 'fiu_upload_file',
        security: fiuajax.security,
        data: fd,
        dataType: 'json',
        contentType: false,
        processData: false,
    },
    success: function(response){
        var dataObj = jQuery.parseJSON(response);
        if(dataObj.message == 'error') {
            jQuery('.fiu_validation').html('The following error occured: '+dataObj.desc);
        }
        else if(dataObj.message == 'success') {
            jQuery('.fiu_file').val('');
        }
        console.log(response);
    }
});
1

複数のデータと複数のファイルがある場合のいくつかの変更されたコード

var fd = new FormData();
var data = jQuery('#yourformID').serializeArray();
jQuery.each(data,function(key,input){
    fd.append(input.name,input.value);
});
var file = jQuery(document).find('input[type="file"]');
jQuery.each(jQuery(file), function(i, obj) {
    jQuery.each(obj.files,function(j,file){
        fd.append('files[' + j + ']', file);
    })
});
fd.append('action', 'fiu_upload_file');

任意の入力(1つまたは複数の単純または複数)、textarea、フォームで選択(WP 5.0.3)で機能します

    $('#form').submit(function(e) {
        e.preventDefault();

        var form = $(this);
        var formdata = (window.FormData) ? new FormData(form[0]) : null;
        var data = (formdata !== null) ? formdata : form.serialize();

        formdata.append("action", "fiu_upload_file");

        $.ajax({
            type: 'POST',
            url: fiuajax.ajaxurl,
            contentType: false,
            processData: false,
            dataType: 'JSON',
            status: 200,
            data: formdata,
            success: function(data){                    
                if(data.error == 'true') {
                    $('.msg').html(data.true);                          
                }
                else {
                    $('.msg').html(data.false);                                                                             
                };
            }
        });
    });

およびファイルのみのphp

    foreach ($_FILES as $file) :
        if($file['error'] == UPLOAD_ERR_NO_FILE) :
            continue;
        endif;

        $valid_ext = array( 'jpg' , 'jpeg' , 'png' , 'doc' , 'docx' , 'pdf' , 'xls' , 'xlsx');
        $extension_upload = strtolower(  substr(  strrchr($file['name'], '.')  ,1)  );
        if ( in_array($extension_upload,$valid_ext) ) :
            $name_upload = uniqid() . $file['name'];
            $url_insert = trailingslashit( plugin_dir_path( dirname( __FILE__ ) ) ) . 'uploads';
            wp_mkdir_p($url_insert);
            $name_insert = trailingslashit($url_insert) . $name_upload;
            $action = move_uploaded_file($file['tmp_name'],$name_insert);
            $msg_true = 'Upload ok ';
        else :
            $msg_error = 'Upload error';
        endif;
    endforeach;

    $result = !isset($msg_error);
    $msg = array();

    if($result) :
        $msg['error'] = 'true';
        $msg['true'] = $msg_true;
    else :
        $msg['error'] = 'false';
        $msg['false'] = $msg_error;
    endif;



    header('Content-Type: application/json');
    echo json_encode($msg);
0
Otis Feru