【问题标题】:WP Rest API upload imageWP Rest API 上传图片
【发布时间】:2016-05-25 08:50:16
【问题描述】:

我正在尝试通过 Wordpress REST api v2 上传图片。到目前为止,我所做的只是在 wordpress 媒体库中创建空条目。这意味着它们有图像名称,但没有实际图像。

POST 请求:

http://localhost/wordpress/wp-json/wp/v2/media

Authorization: Basic d29yZHByZXNzOndvcmRwcmVzcw==
Content-Type: application/json
Content-Disposition: attachment;filename=map2.jpg

{
  "source_url" : "file:///C:/Users/x/Desktop/map2.jpg"
}

回复:

{
  "id": 127,
  "date": "2016-05-25T08:43:30",
  "date_gmt": "2016-05-25T08:43:30",
  "guid": {
    "rendered": "http://localhost/wordpress/wp-content/uploads/2016/05/map2-3.jpg",
    "raw": "http://localhost/wordpress/wp-content/uploads/2016/05/map2-3.jpg"
  },
  "modified": "2016-05-25T08:43:30",
  "modified_gmt": "2016-05-25T08:43:30",
  "password": "",
  "slug": "map2-3",
  "status": "inherit",
  "type": "attachment",
  "link": "http://localhost/wordpress/map2-3/",
  "title": {
    "raw": "map2-3",
    "rendered": "map2-3"
  },
  "author": 1,
  "comment_status": "open",
  "ping_status": "closed",
  "alt_text": "",
  "caption": "",
  "description": "",
  "media_type": "image",
  "mime_type": "image/jpeg",
  "media_details": {},
  "post": null,
  "source_url": "http://localhost/wordpress/wp-content/uploads/2016/05/map2-3.jpg",
  "_links": {
    "self": [
      {
        "href": "http://localhost/wordpress/wp-json/wp/v2/media/127"
      }
    ],
    "collection": [
      {
        "href": "http://localhost/wordpress/wp-json/wp/v2/media"
      }
    ],
    "about": [
      {
        "href": "http://localhost/wordpress/wp-json/wp/v2/types/attachment"
      }
    ],
    "author": [
      {
        "embeddable": true,
        "href": "http://localhost/wordpress/wp-json/wp/v2/users/1"
      }
    ],
    "replies": [
      {
        "embeddable": true,
        "href": "http://localhost/wordpress/wp-json/wp/v2/comments?post=127"
      }
    ]
  }
}

我没有收到任何错误,一切似乎都正常,除了 response->post 和 response->media_details 为空或为空。当然图片本身不会上传。

基于这张GitHub WP-API Adding Media 票,我应该发送2 个请求。首先POST 请求应该返回带有post 对象的数据。我会通过PUT方法发送这个帖子对象,并且应该上传图片......因为我没有帖子对象,这是不可能的。

任何想法我做错了什么?

【问题讨论】:

    标签: wordpress


    【解决方案1】:

    wordpress api 不支持侧载图像,因此您必须进行一些更改。

    首先,您的 content-type 应该是 image/jpeg 而不是 application/json,请记住 content-type 应该反映您传递的数据,并且POST 媒体请求需要一个图像。

    为了适应内容类型,您必须进行的另一项更改是您传递数据的方式。不要使用 source_url 参数发送它,而是尝试将其作为二进制文件传递。

    我要提到的最后一件事是 wp/v2 调用在某些情况下会返回 3XX 状态。跟踪这些重定向并将这些请求重做到这些新 URL 将很有用。

    我在传递 JPEG 图像时遇到了一些问题,但 PNG 图像运行良好。这是我用来上传 png 媒体的 curl 示例:

    curl --request POST \
    --url http://www.yoursite.com/wp-json/wp/v2/media \
    --header "cache-control: no-cache" \
    --header "content-disposition: attachment; filename=tmp" \
    --header "authorization: Basic d29yZHByZXNzOndvcmRwcmVzcw==" \
    --header "content-type: image/png" \
    --data-binary "@/home/web/tmp.png" \
    --location
    

    【讨论】:

    • 谢谢。您对内容类型的标注帮助我解决了我遇到的错误。
    • @rtrigoso 我可以上传文件,但 WordPress 无法将其识别为图像。我可以看到文件大小约为 300KB。可能有什么问题? PS:我将文件作为base64编码的数据字符串发送。
    • 我实际上需要两个电话。一个用于创建和上传图像;其他用于添加-data 字段。这些调用都不能使图像成为给定"post":"$post_id" 中的精选图像,可能需要第三次调用...
    • @rtrigoso 我尝试使用与您在帖子中编写的相同标题并传递二进制数据但无法创建媒体。通过邮递员完成。所有媒体的唯一返回列表
    【解决方案2】:

    我使用 PHP cUrl 的工作答案

    <?php
    
    $curl = curl_init();
    
    $data = file_get_contents('C:\test.png');
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => "http://woo.dev/wp-json/wp/v2/media",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => "",
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 30,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_HTTPHEADER => array(
        "authorization: Basic XxxxxxxXxxxxXx=",
        "cache-control: no-cache",
        "content-disposition: attachment; filename=test.png",
        "content-type: image/png",
      ),
      CURLOPT_POSTFIELDS => $data,
    ));
    
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    curl_close($curl);
    
    if ($err) {
      echo "cURL Error #:" . $err;
    } else {
      echo $response;
    }
    

    【讨论】:

    • 可以添加执行此请求后得到的响应吗?
    • 为 curl_setopt_array 点赞。以前从未见过,也不太清楚。
    【解决方案3】:

    在 2020 年 1 月,使用带有 nginx 的 wordpress 5.3.2 对我有用的解决方案是:

     function uploadFile($token, $archivo) {
        $file = file_get_contents( $archivo );
        $mime = mime_content_type( $archivo );
        $url =  BASEAPI. 'wp-json/wp/v2/media';
        $ch = curl_init();
    
        curl_setopt( $ch, CURLOPT_URL, $url );
        curl_setopt( $ch, CURLOPT_POST, 1 );
        curl_setopt($ch,  CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $file );
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        curl_setopt( $ch, CURLOPT_HTTPHEADER, [
            'Content-Type: '.$mime,
            'Content-Disposition: attachment; filename="'.basename($archivo).'"',
            'Authorization: Bearer ' .$token,
        ] );
        $result = curl_exec( $ch );
        curl_close( $ch );
        print_r( json_decode( $result ) );
    }
    

    令牌是授权 JWT 令牌,$archivo 是文件路径。

    【讨论】:

    • CURLOPT_BINARYTRANSFER 已弃用
    【解决方案4】:

    对于任何寻找 JS 解决方案的人,以下是我使用 Axios 使其工作的方法。我将跳过授权实现,因为有几个选项(oAuth、JWT、Basic)。

    const fs = require('fs');
    const axios = require('axios');
    
    axios({
      url: 'http(s)://{your-wp-domain}/wp-json/wp/v2/media',
      method: 'POST',
      headers: {
        'Content-Disposition':'attachment; filename="file.jpg"',
         Authorization: {your-authorization-method},
        'Content-Type':'image/jpeg'
        },
        data: fs.readFileSync('path/to/file.jpg', (err, data) => {
          if (err) {
            console.log(err);
          }
        });
    })
     .then(res => {
       console.log(res.data);
     })
     .catch(err => {
       console.log(err);
     });
    

    【讨论】:

    • 可以分享一下要发送的请求正文吗?
    • 我认为这行不通,因为fs 在浏览器中不可用。
    【解决方案5】:

    在尝试使用 wp_remote_post 运行图像上传(出于多种原因不想使用 curl)后,我想出了以下可行的解决方案:

    // Upload image to wordpress media library
    
    $file = @fopen( 'image.jpg', 'r' );
    $file_size = filesize( 'image.jpg' );
    $file_data = fread( $file, $file_size );
    $args = array(
        'headers'     => array(
            'Authorization' => 'Basic ' . base64_encode( 'USERNAME:PASSWORD' ),
            'accept'        => 'application/json', // The API returns JSON
            'content-type'  => 'application/binary', // Set content type to binary
            'Content-Disposition' => 'attachment; filename=nameoffileonserver.jpg'
        ),
        'body'        => $file_data
        );
    
    
    
    $api_response = wp_remote_post( 'http://myserver.com/wp-json/wp/v2/media', $args);
    

    【讨论】:

    • 干净、简单、直接 - 可用于其他语言,如 C# 并进行一些修改。
    【解决方案6】:

    这里你可以使用这个代码sn-p。这适用于我使用 Wordpress API REST

    <?php
    //Add this to your function.php
    function upload_image( $imageID, $login ) {
      $request_url = 'https://DOMAINNAME.com/wp-json/wp/v2/media'; //change the domainname
        $image_file_path = get_attached_file($imageID); //change this to your file meda path if your not throwing media file to other server
      $image = file_get_contents( $image_file_path );
        $mime = mime_content_type( $image_file_path );
    
      $api_media_response = wp_remote_post( $request_url, array(
            'headers' => array(
                'Authorization' => 'Basic ' . base64_encode( $login ), //login format USERNAME:PASSWORD
                'Content-Disposition' => 'attachment; filename='.basename($image_file_path).'',
                'Content-Type' => $mime
            ),
            'body' => $image
        ) );
    
      //this function return wp_remote_post
      // more info => https://developer.wordpress.org/reference/functions/wp_remote_post/
    }
    

    【讨论】:

    • 你能解释一下用法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    相关资源
    最近更新 更多