在 Wordpress 中上传 Ajax 文件 - 无法传递 FormData
Posted
技术标签:
【中文标题】在 Wordpress 中上传 Ajax 文件 - 无法传递 FormData【英文标题】:Ajax file upload in Wordpress - can't pass FormData 【发布时间】:2015-03-23 09:43:45 【问题描述】:我制作了一个脚本,它使用 $.ajax 和 FormData 将两个表单对象传递给 php。一个表单对象是文本,另一个是文件。
它作为一个独立的脚本运行良好。但是,在我将它作为插件添加到 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版本,没有变化
【问题讨论】:
fiuajax.ajaxurl = wp ajax 的正确 url? 是的,我仔细检查了 ajaxurl 和安全随机数。我尝试通过 $.post 拨打电话,但也没有运气。 ok 显示你的 php ......基本上,如果你把echo "hello";
放在你的代码和你的成功函数 console.log(response) 中。 jQuery 看起来是正确的,所以一旦 ajaxurl = '' 如果它没有触发它,你的 add_action 钩子有错误
当我从 ajax 调用中注释掉 data: fd 时,一切正常。但是当我添加 data:fd 时,它给了我一个 javascript 错误。所以 PHP 绝对是正确的。
错误是什么?你也应该显示你的 html 输出..
【参考方案1】:
试试这个:
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');
【讨论】:
它不起作用:/ processData 和 contentType 是返回 0 的原因。此外,contentType 根本不发送 multipart/form-data。相反,它发送纯文本。我检查了formdata,似乎还可以,所以不是这样。太奇怪了。它必须与 Wordpress 相关。 好吧 0 意味着你没有放 exit();在你的 php 函数中......现在在 wp 安装上测试上面的代码,看看有什么问题。 我尝试了 exit() 和 die(),但没有运气。不过感谢您的帮助,我很感激。我决定采用非基于 ajax 的方法。 好吧,你可能会接受这个作为正确答案,它可以帮助遇到这个问题的其他人! 这是一个很好的努力,但对我使用最新的 wordpress 不起作用【参考方案2】:我设法做到了。该代码适用于最新版本的 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 核心功能上传附件的代码。
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) );
谢谢。
【讨论】:
您能描述一下您在这里所做的不同而重要的事情吗?重要的部分应该在您的答案中很容易看到。 当然:首先,我使用 XMLHttpRequest 发送数据,而不是 jQuery ajax。这意味着您可以将其调整为纯 JS。注意 .setRequestHeader("enctype","multipart/form-data") 对这个方法很重要。 PHP 部分也非常有用,因为它需要使用 WP 核心函数处理接收到的数据所需的文件。谢谢。 详细信息应添加到您的答案中。点击“编辑” 优秀。谢谢你。欢迎使用 ***!【参考方案3】:适用于任何输入(一个或多个简单或多个)、文本区域、在您的表单中选择 (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);
// your code if you want an action ...
;
);
);
和 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(pathinfo($file['name'], PATHINFO_EXTENSION));
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);
【讨论】:
【参考方案4】:我加了
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);
);
【讨论】:
【参考方案5】:这里有一些修改过的代码,以防您有多个数据和多个文件
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');
【讨论】:
以上是关于在 Wordpress 中上传 Ajax 文件 - 无法传递 FormData的主要内容,如果未能解决你的问题,请参考以下文章
如何在 wordpress 中通过 jQuery/Ajax 上传图片
如何在Wordpress环境中使用Ajax将附件发送到服务器端[重复]