WP Rest API загрузить изображение

Я пытаюсь загрузить изображение через 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 является нулевым или пустым. Конечно, само изображение не загружается.

На основе https://github.com/WP-API/WP-API/issues/1768 Я должен отправить 2 запроса. Первый запрос POST должен вернуть данные с пост-объектом. Я бы отправил этот объект сообщения через метод PUT, и изображение должно быть загружено..., так как у меня нет объекта сообщения, это невозможно.

Есть идеи, что я делаю не так?

7 ответов

Загрузка изображений не поддерживается API WordPress, поэтому вам придется внести некоторые изменения.

Во-первых, ваш тип контента должен быть image/jpeg, а не application / json, помните, что тип контента должен отражать данные, которые вы передаете, а медиа-запрос POST ожидает изображение.

Еще одно изменение, которое вы должны сделать, чтобы приспособить тип контента, - это способ передачи данных. Вместо того, чтобы отправлять его с параметром source_url, попробуйте передать его в виде двоичного файла.

И последнее, что я хотел бы упомянуть, это то, что вызовы wp/v2 несколько раз возвращают статус 3XX. Было бы полезно следить за этими перенаправлениями и перенаправлять эти запросы на новые URL-адреса.

У меня были некоторые проблемы с передачей изображений JPEG, но изображения PNG работали хорошо. Вот пример curl, который я использую для загрузки png медиа:

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

Для тех, кто ищет решение 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);
 });

Мой рабочий ответ с использованием 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;
}

В январе 2020 года с использованием wordpress 5.3.2 с nginx решение, которое работает для меня:

 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 - это путь к файлу.

Здесь вы можете использовать этот фрагмент кода. Это работает для меня с использованием 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/
}

После попытки запустить загрузку изображений с помощью 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);

если вы хотите загрузить изображение в WordPress rest API с помощью nuxtjs или vuejs, вы можете использовать следующий код:

в шаблоне:

      <input style="display: none;" type="file" @change="onFileSelected"
<button @click="onUpload" />

в данных:

        data() {
return {
  selectedFile: null,
  previewImage: null
};}

в методах:

        onFileSelected(event) {
  this.selectedFile = event.target.files[0];
   }

   onUpload() {
const fd = new FormData();
fd.append("file", this.selectedFile, this.selectedFile.name);
fd.append("title", "pedram");
fd.append("caption", "this is caption");


/* file reader for prview image */
const reader = new FileReader();
reader.readAsDataURL(this.selectedFile);
reader.onload = e =>{
                this.previewImage = e.target.result;
};
/* set request header */
const headers = {
  'Content-Disposition':`attachment; filename=${this.selectedFile.name}`,
   Authorization: "Bearer" + this.$cookiz.get("AdminToken"),
  'content-type': 'image' 
};

  this.$axios.post('/wp-json/wp/v2/media', fd, { headers })
    .then(res => {
      console.log(res);
    })
    .catch(err => {
      console.log(err);
    });
},

если вы хотите просмотреть изображение, вы можете использовать программу чтения файлов и сохранить его в переменной данных, а затем использовать данные вместо изображения src, как показано ниже:

      <img @click="$refs.fileInput.click()" v-if="previewImage" :src="previewImage" alt="" class="w-100" />

Мне потребовался один день, чтобы решить проблему, я надеюсь, что приведенные выше коды помогут

Другие вопросы по тегам