# APIを使ってファイルをアップロードするにはどうすればいいですか？

**URL:** https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310
**Category:** Development
**Tags:** rest-api
**Created:** [2021 年 9 月 23 日午後 1:36 UTC](https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310 "2021-09-23T13:36:45Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![JQ331](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@JQ331](https://meta.discourse.org/u/JQ331)
#### Post date: [2021 年 9 月 23 日午後 1:36 UTC](https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310/1 "2021-09-23T13:36:45Z")

</div>

API を通じてファイルのアップロードを許可する方法がわからず困っています。以下の有益な投稿はご覧になりましたか：[How to upload a file via API and get it's URL? - #3 by Daniil\_Bazhenov](https://meta.discourse.org/t/how-to-upload-a-file-via-api-and-get-its-url/123732/3)

しかし、実際の構文が記載されておらず、そこが私のつまずきポイントです。AJAX コールの実際の構文をご存知の方はいらっしゃいますか？

私が現在試しているコードは以下の通りです：

```plaintext
 method: "post",
      url: [site]/uploads.json,
      contentType: "multipart/form-data",
      data: {
        type: "composer",
        file: '/path_to_file_from_users_machine'
      },
      headers: {
        "User-Api-Key": key
      },
      dataType: "json",
    }).then((result)=>{

```

しかし、これでは 422 エラーが返ってきます。構文に何か問題があるようです。どのようにすれば動作するようにできますか？

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [2021 年 9 月 27 日午後 3:12 UTC](https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310/2 "2021-09-27T15:12:17Z")

</div>

> [@JQ331](#):
>
> 422 応答

その応答に付随するメッセージはありますか？それにより、より詳細な情報が得られるはずです。

---

<div class="post-metadata">

### Author: ![JQ331](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@JQ331](https://meta.discourse.org/u/JQ331)
#### Post date: [2021 年 9 月 27 日午後 4:01 UTC](https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310/3 "2021-09-27T16:01:19Z")

</div>

私の確認限りでは、このエラーメッセージが唯一の応答です：  
`Error: Request failed with status code 422`

また、ログにも何も表示されていません。

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [2021 年 9 月 27 日午後 8:38 UTC](https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310/4 "2021-09-27T20:38:40Z")

</div>

動作している Node の例を以下に示します。参考になるかもしれません：

> [@How to upload images via API with Node.js?](https://meta.discourse.org/t/how-to-upload-images-via-api-with-node-js/172605/2?u=blake):
>
> I got this to work, like this: import Axios from "axios"; import FormData from "form-data"; import fs from "fs"; const http = Axios.create({ baseURL: "https://forum.zeebe.io", headers: { "Api-Key": "...", "Api-Username": "...", "Content-Type": "application/json", Accept: "application/json", }, }); http.interceptors.request.use((config) =\> { if (config.data instanceof FormData) { Object.assign(config.headers, config.data.getHeaders()); } return config; }); …

---

<div class="post-metadata">

### Author: ![JQ331](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@JQ331](https://meta.discourse.org/u/JQ331)
#### Post date: [2021 年 9 月 27 日午後 9:53 UTC](https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310/5 "2021-09-27T21:53:05Z")

</div>

@blake さん、どうもありがとうございます。以前は見つからなかった（似たようなものを検索していたにもかかわらず）とても役立つ投稿ですね。これで確実に前に進めそうです。ただ、一点気になったことがあります。リンク先のコードにあるこの行です：

`const file = fs.readFileSync(filename);`

この行は、Discourse にアップロードされるものが実際のファイルそのものではなく、ファイルの内容（上記のコードでは、ファイル変数はファイルを読み取って返された文字列に等しい）であることを示唆しています。これは私にとって意外で、バイナリファイル（またはメディアファイル）のアップロードに対してそれが何を意味するのか疑問に思います（サイズが適切であれば、メディアファイルは Discourse に直接アップロードできますが、まずそれらを読み取る方法がどうなるかよくわかりません）。

でも、確認してみます。

---

<div class="post-metadata">

### Author: ![dennisjbr](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/dennisjbr/32/444916_2.png) [@dennisjbr](https://meta.discourse.org/u/dennisjbr)
#### Post date: [2024 年 9 月 25 日午後 5:35 UTC](https://meta.discourse.org/t/how-to-upload-files-through-the-api/204310/6 "2024-09-25T17:35:39Z")

</div>

皆さん、こんにちは。苦労と試行錯誤の末、Discourseへのファイルアップロードが機能するPHPサンプルを共有できると思いました。どうぞ。また、元々は [communiteq/discourse-api-php: PHP API client for Discourse (github.com)](https://github.com/communiteq/discourse-api-php/tree/master) の更新されたライブラリを作成しています。

```plaintext
<?php
	
	$curl = curl_init();
	
	curl_setopt_array($curl, array(
		CURLOPT_URL => 'https://example.com/uploads.json',
		CURLOPT_RETURNTRANSFER => true,
		CURLOPT_ENCODING => '',
		CURLOPT_MAXREDIRS => 10,
		CURLOPT_TIMEOUT => 0,
		CURLOPT_FOLLOWLOCATION => true,
		CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
		CURLOPT_CUSTOMREQUEST => 'POST',
		CURLOPT_POSTFIELDS => array(
			'type' => 'composer',
			'synchronous' => 'true',
			'file'=> new CURLFILE('/directory/filename.txt')),
		CURLOPT_HTTPHEADER => array(
			'Content-Type: multipart/form-data',
			'Accept: application/json',
			'Api-Key: <your api key>',
			'Api-Username: <your api user id>'
		),
	));
	
	$response = curl_exec($curl);
	$info = curl_getinfo($curl);
	curl_close($curl);
	print_r(json_decode($response,1));
	print_r($info);
?>

```

サンプル出力：

```plaintext
Array
(
    [id] => 627
    [url] => https://example.com/uploads/default/original/1X/4661e3a873857e04440bcc3e4290e241eb6c08d7.txt
    [original_filename] => filename.txt
    [filesize] => 461
    [width] => 
    [height] => 
    [thumbnail_width] => 
    [thumbnail_height] => 
    [extension] => txt
    [short_url] => upload://a2D9hHsjwsdrVWkzlu5Go4c1VvV.txt
    [short_path] => /uploads/short-url/a2D9hHsjwsdrVWkzlu5Go4c1VvV.txt
    [retain_hours] => 
    [human_filesize] => 461 Bytes
    [dominant_color] => 
    [thumbnail] => 
)
Array
(
    [url] => https://example.com/uploads.json
    [content_type] => application/json; charset=utf-8
    [http_code] => 200
    [header_size] => 422
    [request_size] => 1244
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.029617
    [namelookup_time] => 0.00046
    [connect_time] => 0.003265
    [pretransfer_time] => 0.003592
    [size_upload] => 911
    [size_download] => 460
    [speed_download] => 15531
    [speed_upload] => 30759
    [download_content_length] => 460
    [upload_content_length] => 911
    [starttransfer_time] => 0.029604
    [redirect_time] => 0
    [redirect_url] => 
    [primary_ip] => 192.168.192.40
    [certinfo] => Array
        (
        )

    [primary_port] => 80
    [local_ip] => 192.168.192.18
    [local_port] => 61613
    [http_version] => 2
    [protocol] => 1
    [ssl_verifyresult] => 0
    [scheme] => http
    [appconnect_time_us] => 0
    [connect_time_us] => 3265
    [namelookup_time_us] => 460
    [pretransfer_time_us] => 3592
    [redirect_time_us] => 0
    [starttransfer_time_us] => 29604
    [total_time_us] => 29617
    [effective_method] => POST
    [capath] => 
    [cainfo] => 
)

```

また、こちらのPostmanのサンプルからも非常に多くの助けを得ました： [Creates an upload | Discourse | Postman API Network](https://www.postman.com/api-evangelist/discourse/request/4jps7a1/creates-an-upload?tab=overview)

よろしく
