API를 통해 파일을 업로드하는 방법?

API를 통해 파일 업로드를 허용하는 방법을 알아보고 있습니다. API 문서를 참고하고 있습니다. 다음 유용한 게시물을 확인했습니다: How to upload a file via API and get it's URL? - #3 by Daniil_Bazhenov,

하지만 실제 구문은 제시하지 않고 있어, 이것이 바로 제가 어려움을 겪고 있는 부분입니다. ajax 호출의 실제 구문을 아시는 분이 계신가요?

현재 작성한 코드는 다음과 같습니다:

 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 응답을 반환합니다. 구문에 뭔가 문제가 있는 것 같습니다. 어떻게 하면 정상적으로 동작하게 만들 수 있을까요?

응답과 함께 메시지가 있나요? 그러면 더 많은 정보를 얻을 수 있을 것입니다.

제가 보기에는 이 응답이 유일합니다:
Error: Request failed with status code 422

로그에서도 아무것도 보이지 않습니다.

다음은 누군가가 성공적으로 작동시킨 노드(Node) 예시입니다. 도움이 될 수 있습니다:

정말 감사합니다, @blake. 이전에 보지 못했던(비슷한 글을 검색해 보았지만) 매우 유용한 글입니다. 앞으로 진행하는 데 분명 도움이 될 것 같습니다. 다만 한 가지 눈길이 가는 부분이 있습니다. 링크된 코드에 있는 이 줄입니다:
const file = fs.readFileSync(filename);

이 줄은 discourse에 업로드하는 것이 실제로 파일 자체가 아니라 파일의 내용(위 코드에서는 file 변수가 파일을 읽어서 반환된 문자열)이라는 것을 암시합니다. 제게는 다소 놀라운 부분이고, 바이너리 파일(또는 미디어 파일)을 업로드할 때 이것이 어떤 의미를 갖는지 궁금합니다. 미디어 파일은 용량이 허용된다면 discourse에 직접 업로드하면 문제없이 작동하지만, 먼저 파일을 읽어 올 경우 어떻게 되는지는 잘 모르겠습니다.

하지만 직접 확인해 보겠습니다.

여러분 안녕하세요, 좀 고생하고 시행착오를 거친 끝에 Discourse에 파일을 업로드하는 데 사용되는 PHP 샘플 코드를 공유하려고 합니다! 아래에 첨부합니다. 또한, communiteq/discourse-api-php: PHP API client for Discourse (github.com)에서 가져온 라이브러리를 업데이트하고 있습니다:

<?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);
?>

샘플 출력:

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

감사합니다