WordPress和AJAX-上传图像作为特色图片

8

我在使用带有Ajax的WordPress前端表单,并且需要支持处理和上传特色图片。我的问题具体涉及到特色图片。我的HTML代码类似于:

<form id="msform" action="#" method="post" enctype="multipart/form-data">
//inputs of various nature
<input type="file" name="main_image" id="main_image"  multiple="false" value="" accept=".png, .jpg, .jpeg, .gif"/>
<input type="submit" class="submit" value="Publish"/>
</form>

我通过以下JQuery将数据发送到一个php函数(遵循Wordpress方法):

function apfaddpost() {
    var formData = $('#msform').serialize();
    formData.append('main_image', $('#main_image')[0].files[0]); //here should be the problem
    jQuery.ajax({
        type: 'POST',
        url: apfajax.ajaxurl,
        data: formData + '&action=apf_addpost', //here I send data to the php function calling the specific action
        processData: false,
        contentType: false

        success: function(data, textStatus, XMLHttpRequest) {
            var id = '#apf-response';
            jQuery(id).html('');
            jQuery(id).append(data);
            resetvalues();
        },

        error: function(MLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown);
        }

    });
}

我的php函数大致如下

function apf_addpost() {
    require_once(ABSPATH . "wp-admin" . '/includes/image.php');
    require_once(ABSPATH . "wp-admin" . '/includes/file.php');
    require_once(ABSPATH . "wp-admin" . '/includes/media.php');
    $file_handler = 'main_image';
    $attach_id = media_handle_upload($file_handler,$pid );
    update_post_meta($pid,'_thumbnail_id',$attach_id);
}

重要的是说:所有其他数据(如标题、描述和标签)都正确序列化并发送。问题出在图片上。我也尝试过使用$_FILES[]处理程序,但没有成功,我想我的ajax代码不太好。你能帮我吗?如果你有任何其他解决这个问题的方法,请分享!提前感谢您。
【已解决】编辑
感谢下面的答案,我刚刚把我的ajax改成了:
function apfaddpost() {
    var fd = new FormData($('#msform')[0]);
    fd.append( "main_image", $('#main_image')[0].files[0]);
    fd.append( "action", 'apf_addpost');      
   //Append here your necessary data
    jQuery.ajax({
        type: 'POST',
        url: apfajax.ajaxurl,
        data: fd, 
        processData: false,
        contentType: false,

        success: function(data, textStatus, XMLHttpRequest) {
            var id = '#apf-response';
            jQuery(id).html('');
            jQuery(id).append(data);
            resetvalues();
        },

        error: function(MLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown);
        }

    });
}

我发现FormData()可以序列化文件,而.serialize()方法不行。有了这个发现,后面的工作就很简单了。谢谢。
2个回答

11

请尝试:

我已修改了您的代码。

Jquery(添加了FormData()和append)

function apfaddpost() {
    var fd = new FormData();
    fd.append( "main_image", $('#main_image')[0].files[0]);
    fd.append( "action", 'apf_addpost');      
   //Append here your necessary data
    jQuery.ajax({
        type: 'POST',
        url: apfajax.ajaxurl,
        data: fd, 
        processData: false,
        contentType: false

        success: function(data, textStatus, XMLHttpRequest) {
            var id = '#apf-response';
            jQuery(id).html('');
            jQuery(id).append(data);
            resetvalues();
        },

        error: function(MLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown);
        }

    });
}

function.php文件中,我添加了文件上传代码。

/******FILE UPLOAD*****************/
function upload_user_file( $file = array() ) {    
    require_once( ABSPATH . 'wp-admin/includes/admin.php' );
    $file_return = wp_handle_upload( $file, array('test_form' => false ) );
    if( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) {
        return false;
    } else {
        $filename = $file_return['file'];
        $attachment = array(
            'post_mime_type' => $file_return['type'],
            'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
            'post_content' => '',
            'post_status' => 'inherit',
            'guid' => $file_return['url']
        );
        $attachment_id = wp_insert_attachment( $attachment, $file_return['url'] );
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        $attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
        wp_update_attachment_metadata( $attachment_id, $attachment_data );
        if( 0 < intval( $attachment_id ) ) {
          return $attachment_id;
        }
    }
    return false;
}

现在修改您在function.php中的apf_addpost()函数。

function apf_addpost() {
     foreach( $_FILES as $file ) 
     {  
          if( is_array( $file ) ) {
                $attach_id =upload_user_file();  //Call function 
                update_post_meta($pid,'_thumbnail_id',$attach_id);
          }
     }

}

谢谢@vrajesh!你解决了我的问题。我不知道FormData()可以序列化文件。我是Jquery / Ajax的初学者。再次感谢! - middlelady

1

对于在WordPress中使用ajax上传,需要注意以下几点:

HTML

发送图片需要一个带有enctype="multipart/form-data"formenctype属性指定表单提交时如何编码表单数据。默认情况下,它是application/x-www-form-urlencoded,因为我们正在进行文件上传,所以将值更改为multipart/form-data

  <form action="" method="post" enctype="multipart/form-data">
      <input type="file" id="image_upload">
      <button type="button" id="image_upload_btn">Update</button>
  </form>

AJAX

$("#image_upload_btn").click(function (e) {
  e.preventDefault();
  var fd = new FormData();
  var files = $("#image_upload")[0].files;
  fd.append("file", files[0]);
  fd.append("action", "upload_image"); // your ajax function

  if (files.length > 0) {
    jQuery.ajax({
      type: "POST",
      url: ajax_url, //  var ajax_url = " <?= admin_url('admin-ajax.php'); ?>"; pass it in the php file
      processData: false,
      contentType: false,
      data: fd,
      beforeSend: function () {
// Any code you like
      },
      success: function (response) {
// Success code
      },
      error: function (request, status, error) {
        console.log(error);
        alert(request.responseText);
      },
    });
  }
});

我们需要使用FormData()接口来构建一组键/值对,表示我们的表单字段和值(这里是我们的图像文件)。这有助于使用ajax轻松传输文件。
由于我们正在使用WordPress,除了图像文件之外,我们还在FormData()中添加了action参数。
这里需要注意的另一件重要事情是processDatacontentType,如果没有它们,您可能会遇到Uncaught TypeError: Illegal invocation
1. 为什么需要processData
默认情况下,将作为对象传递给数据选项的数据会被处理并转换为ajax的查询字符串,由于我们正在上传文件,因此我们希望设置为false。
2. 为什么需要contentType
默认情况下,对于文件上传,它是application/x-www-form-urlencoded; charset=UTF-8,我们必须显式地将其更改为false以取消任何内容类型标头。

PHP

function upload_image()

{
    if (isset($_FILES['file']['name'])) {
        $filename = $_FILES['file']['name'];

        $location = ;// Your desired location
        $imageFileType = pathinfo($location, PATHINFO_EXTENSION);
        $imageFileType = strtolower($imageFileType);

        $valid_extionsions = array("jpg", "jpeg", "png");

        $response = 0;

        if (in_array($imageFileType, $valid_extionsions)) {
            if (move_uploaded_file($_FILES['file']['tmp_name'], $location)) {
                $response = $location; // this is to return the file path after upload
            }
        }
        echo $response;
        exit;
    }
}
add_action("wp_ajax_upload_image", "upload_image");
add_action("wp_ajax_nopriv_upload_image", "upload_image");

请注意将wp_admin替换为wp_ajaxwp_ajax_nopriv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接