I’m currently working on a plugin to Obsidian to upload blog-posts to ghost. And with that I also want it to upload any pictures used in that document. I’ve spent about 30 hours on this now with a little progress but would need some help to try and speed things along. It was just yesterday I think I bypassed the CORS errors I’ve been having with nginx.
Back to the issue in hand - I now get 500 errors when sending to the API - I suspect I’ve constructed the formdata incorrectly. All information can be seen bellow:
Source:
// Building the image data
let imageData;
if (frontmatter.imageDirectory) {
const imageNamePrefix = frontmatter.imageDirectory.replace(/\//g, "");
imageData = {
"images": [
{
"url": `${BASE_URL}/content/images/${year}/${month}/${imageNamePrefix}-${filename}`,
"ref": imagePath
}
]
}
} else {
imageData = {
"images": [
{
"url": `${BASE_URL}/content/images/${year}/${month}/${filename}`,
"ref": imagePath
}
]
}
}
console.log("imagedata", imageData);
// Make blob https://developer.mozilla.org/en-US/docs/Web/API/Blob
const blob = new Blob([JSON.stringify(imageData)], {
type: "application/json",
});
// Construct formdata of blob
const formData = new FormData();
formData.append("file", blob);
formData.append("purpose", "image");
formData.append("ref", imagePath);
try {
const response = await fetch(`${settings.url}/ghost/api/${version}/admin/images/upload/`, {
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Ghost ${token}`,
},
body: formData
});
if (response.ok) {
// Handle success
const data = await response.json();
console.log(data);
} else {
// Handle errors
console.error("Error:", response.statusText);
console.error("Error:", response.statusText);
console.error("Status Code:", response.status); // Add status code
console.error("Response Headers:", response.headers); // Log response headers
response.text().then(errorText => {
console.error("Error Response Text:", errorText); // Log the response body as text
}).catch(error => {
console.error("Error parsing response text:", error);
});
}
} catch (error) {
console.error("Request error:", error);
}
}
Request headers:
:Authority:
mydomain.com
:Method:
POST
:Path:
/ghost/api/v4/admin/images/upload/
:Scheme:
https
Accept:
*/*
Accept-Encoding:
gzip, deflate, br
Accept-Language:
en-US
Authorization:
Ghost <MY-TOKEN>
Content-Length:
580
Content-Type:
multipart/form-data
Origin:
app://obsidian.md
Sec-Ch-Ua-Mobile:
?0
Sec-Ch-Ua-Platform:
"Linux"
Sec-Fetch-Mode:
cors
Sec-Fetch-Site:
cross-site
User-Agent:
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) obsidian/1.4.5 Chrome/114.0.5735.289 Electron/25.8.0 Safari/537.36
Response headers:
Access-Control-Allow-Headers:
Authorization,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range
Access-Control-Allow-Methods:
GET, POST, OPTIONS
Access-Control-Allow-Origin:
*
Access-Control-Expose-Headers:
Content-Length,Content-Range
Alt-Svc:
h3=":443"; ma=86400
Cache-Control:
no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0
Cf-Cache-Status:
DYNAMIC
Cf-Ray:
8097d87c0b84190d-FRA
Content-Length:
280
Content-Type:
application/json; charset=utf-8
Content-Version:
v5.49
Date:
Wed, 20 Sep 2023 06:00:00 GMT
Deprecation:
version="v4"
Etag:
W/"118-TO41uly8SaFcUo6z2CfflFSlP3I"
Link:
<https://mydomain.com/ghost/api/admin/images/upload/>; rel="latest-version"
Nel:
{"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Report-To:
{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=nUEexVPgiZM6W0xtL2SDloBn1%2F%2FmZeisLhIh1Dbgx0PZvlofdEvKRI6w1dU9quzeeFjcEQzNis7YSs1XhAmS1rHKlOv9zKdG8Q7lSdoRtJoHekCB%2FjKWLErdqDH9L6rmfEuPuXJRD8nC"}],"group":"cf-nel","max_age":604800}
Server:
cloudflare
Vary:
Accept-Version, Accept-Encoding
X-Powered-By:
Express
Console error message:
Error Response Text: {"errors":[{"message":"An unexpected error occurred, please try again.","context":"Multipart: Boundary not found","type":"InternalServerError","details":null,"property":null,"help":null,"code":"UNEXPECTED_ERROR","id":"ef416110-577a-11ee-ad51-8f5ac464e714","ghostErrorCode":null}]}
Thank you for any help!