在WordPress中上传Ajax文件 – 无法传递FormData

我创建了一个脚本,它使用$ .ajax和FormData将两个表单对象传递给PHP。 一个表单对象是文本,另一个是文件。 它作为一个独立的脚本运行良好。 但是,在我将它作为插件添加到Wordpress之后,它一直给我"Uncaught TypeError: Illegal invocation"

我不能序列化formdata,因为那时我将无法将文件传递给PHP中的回调函数。

JS在ajax调用之前涉及FormData:

 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版本,没有变化

试试这个 :

 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'); 

我补充道

  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); } }); 

我设法做到了。 该代码适用于最新版本的Wordpress(4.9.4)

首先,我使用XMLHttpRequest来发送数据而不是jQuery ajax。 这意味着您可以将其改编为纯JS。 注意xhttp.setRequestHeader("enctype","multipart/form-data"); 这对于使用此方法传递FormData至关重要。

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核心function上传附件的代码。

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 '
'; print_r($upload_result); echo '

' ; 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) );

谢谢。

这里有一些修改过的代码,以防你有多个数据和多个文件

 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');