Please help, 2 weeks stuck. So far no answers works, no AI, nobody, no workaround, I have no idea where to look anymore.
Uploading images on development works perfect, on production 405. Add headers, take headers, change CORS, use Axios, change to fetch, clear cache, downgrade Nextjs, try different npm's etc... No idea on what to do next.
ON FRONT
const createImagesSrc = async (
imageFileToAdd: File[]
): Promise<AxiosResponse | null> => {
try {
const formData = new FormData();
imageFileToAdd.forEach((image) => {
formData.append("images", image);
});
const uploadResponse = await axios.post("/api/upload", formData, {
})
if (uploadResponse.status === 200) {
uploadResponse.data.uploadResponses.forEach(
(response: any, index: number) => {
imageSrc.push(response.secure_url);
}
);
return uploadResponse;
} else {
console.error("Failed to upload images");
return null;
}
} catch (error) {
console.error(error);
return null;
}
};
ON BACK
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET,
});
export async function POST(request: Request) {
const data = await request.formData();
const files = data.getAll("images");
if (files.length === 0) {
return NextResponse.json({
success: false,
message: "No images to upload.",
});
}
const uploadPreset = "yfhyp9my";
const uploadResponses: any[] = [];
for (const file of files) {
// @ts-ignore
const bytes = await file.arrayBuffer();
const buffer = Buffer.from(bytes);
const response = await new Promise((resolve, reject) => {
cloudinary.uploader
.upload_stream({ upload_preset: uploadPreset }, (error, result) => {
if (error) {
reject(error);
}
resolve(result);
})
.end(buffer);
});
uploadResponses.push(response);
}
return NextResponse.json({ success: true, uploadResponses });
}
NEXT.CONFIG.JS
const nextConfig = {
async headers() {
return [
{
// matching all API routes
source: "/api/:path*",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "coolbananas.org, localhost:3000" },
{
key: "Access-Control-Allow-Methods",
value: "GET,OPTIONS,PATCH,DELETE,POST,PUT",
},
{
key: "Access-Control-Allow-Headers",
value:
"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
},
],
},
];
},
images: {
remotePatterns: [
{
protocol: "https",
hostname: "res.cloudinary.com",
port: "",
pathname: "/jpsm83/image/upload/**",
},
{
protocol: "https",
hostname: "lh3.googleusercontent.com",
},
{
protocol: "https",
hostname: "restcountries.com",
},
],
},
};
ERROR
POST https://www.coolbananas.org/api/upload 405 (Method Not Allowed)
AxiosError {message: 'Request failed with status code 405', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
code
:
"ERR_BAD_REQUEST"
config
:
{transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}
message
:
"Request failed with status code 405"
name
:
"AxiosError"
request
:
XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
response
:
config
:
adapter
:
(2) ['xhr', 'http']
data
:
FormData {}
env
:
{FormData: ƒ, Blob: ƒ}
headers
:
AxiosHeaders {Accept: 'application/json, text/plain, /', Content-Type: false}
maxBodyLength
:
-1
maxContentLength
:
-1
method
:
"post"
timeout
:
0
transformRequest
:
[ƒ]
transformResponse
:
[ƒ]
transitional
:
{silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false}
url
:
"/api/upload"
validateStatus
:
ƒ (e)
xsrfCookieName
:
"XSRF-TOKEN"
xsrfHeaderName
:
"X-XSRF-TOKEN"
[[Prototype]]
:
Object
data
:
""
headers
:
AxiosHeaders {access-control-allow-credentials: 'true', access-control-allow-headers: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Ver…h, Content-MD5, Content-Type, Date, X-Api-Version', access-control-allow-methods: 'GET,OPTIONS,PATCH,DELETE,POST,PUT', access-control-allow-origin: 'coolbananas.org, localhost:3000', cache-control: 'public, max-age=0, must-revalidate', …}
request
:
XMLHttpRequest
onabort
:
ƒ ()
onerror
:
ƒ ()
onload
:
null
onloadend
:
ƒ onloadend()
onloadstart
:
null
onprogress
:
null
onreadystatechange
:
null
ontimeout
:
ƒ ()
readyState
:
4
response
:
""
responseText
:
""
responseType
:
""
responseURL
:
"https://www.coolbananas.org/api/upload"
responseXML
:
null
status
:
405
statusText
:
""
timeout
:
0
upload
:
XMLHttpRequestUpload
onabort
:
null
onerror
:
null
onload
:
null
onloadend
:
null
onloadstart
:
null
onprogress
:
null
ontimeout
:
null
[[Prototype]]
:
XMLHttpRequestUpload
withCredentials
:
false
[[Prototype]]
:
XMLHttpRequest
status
:
405
statusText
:
""
[[Prototype]]
:
Object
stack
:
"AxiosError: Request failed with status code 405\n at settle (https://www.coolbananas.org/_next/static/chunks/118-3737272d4a0dcc07.js:37:18624)\n at XMLHttpRequest.onloadend (https://www.coolbananas.org/_next/static/chunks/118-3737272d4a0dcc07.js:37:21902)"
[[Prototype]]
:
Error
This is an issue only in PRODUCTION mode, development is fine. All "keys" been add to Vercel and Vercel is working properly once I can save all data to MongoDB but the images doesnt get create at Cloudinary. I tryed to update CORS at Cloudinary but seen to have no such option on their website. Very frustate, I got pretty bad stuck ;(
- Try to downgrade Nextjs
- Try to add differents npm to handle CORS
- Try to change Axios for Fetch
- Try to add headers manualy 'Content-Type': 'multipart/form-data' on front
- Try to config CORS at next.config.js
- Try every single blog about similar issue
- Try every single answers fron AI
- Try all cloudinary management console docs
- Try to cry for about 10 min
- Nothing works