Having trouble getting files from my NextJS Application

I am building a t3 Typescript Nextjs application and I have a worker which I've set up like this:
const hasValidHeader = (request: Request, env: Env) => {
return request.headers.get('X-CF-Secret') === env.AUTH_KEY_SECRET;
};

function authorizeRequest(request: Request, env: Env, key:string) {
switch (request.method) {
case 'PUT':
case 'DELETE':
return hasValidHeader(request, env);
case 'GET':
return true
default:
return false;
}
}

export default {
async fetch(request:Request, env:Env) {
const url = new URL(request.url);
const key = url.pathname.slice(1);

if (!authorizeRequest(request, env, key)) {
return new Response('Forbidden', { status: 403 });
}

switch (request.method) {
case 'PUT':
await env.R2_BUCKET.put(key, request.body);
return new Response(`Put ${key} successfully!`);
case 'GET':
const object = await env.R2_BUCKET.get(key);

if (object === null) {
return new Response('Object Not Found', { status: 404 });
}

const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set('etag', object.httpEtag);

return new Response(object.body, {
headers,
});
case 'DELETE':
await env.R2_BUCKET.delete(key);
return new Response('Deleted!');

default:
return new Response('Method Not Allowed', {
status: 405,
headers: {
Allow: 'PUT, GET, DELETE',
},
});
}
},
};
const hasValidHeader = (request: Request, env: Env) => {
return request.headers.get('X-CF-Secret') === env.AUTH_KEY_SECRET;
};

function authorizeRequest(request: Request, env: Env, key:string) {
switch (request.method) {
case 'PUT':
case 'DELETE':
return hasValidHeader(request, env);
case 'GET':
return true
default:
return false;
}
}

export default {
async fetch(request:Request, env:Env) {
const url = new URL(request.url);
const key = url.pathname.slice(1);

if (!authorizeRequest(request, env, key)) {
return new Response('Forbidden', { status: 403 });
}

switch (request.method) {
case 'PUT':
await env.R2_BUCKET.put(key, request.body);
return new Response(`Put ${key} successfully!`);
case 'GET':
const object = await env.R2_BUCKET.get(key);

if (object === null) {
return new Response('Object Not Found', { status: 404 });
}

const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set('etag', object.httpEtag);

return new Response(object.body, {
headers,
});
case 'DELETE':
await env.R2_BUCKET.delete(key);
return new Response('Deleted!');

default:
return new Response('Method Not Allowed', {
status: 405,
headers: {
Allow: 'PUT, GET, DELETE',
},
});
}
},
};

I am able to upload images like this in my /api/images/upload route
// import { ratelimit, redis, setRandomKey } from "@/lib/upstash";
import { NextRequest } from "next/server";

export const config = {
runtime: "experimental-edge",
};


export default async function handler(req: NextRequest) {
const { image, email } = await req.json();
if (!image) {
return new Response("Missing image", { status: 400 });
}
if (req.method === "POST") {
const key = "MyFile";
const r2 = await (
fetch(`https://dev_worker.alber.workers.dev/${key}`, {
method: "PUT",
headers: {
"X-CF-Secret": process.env.R2_AUTH_KEY_SECRET as string,
},
body: Uint8Array.from(atob(image.replace(/^data[^,]+,/, "")), (v) =>
v.charCodeAt(0),
),
})
);
return new Response(JSON.stringify({ key }));
} else {
return new Response("Method Not Allowed", { status: 405 });
}
}
// import { ratelimit, redis, setRandomKey } from "@/lib/upstash";
import { NextRequest } from "next/server";

export const config = {
runtime: "experimental-edge",
};


export default async function handler(req: NextRequest) {
const { image, email } = await req.json();
if (!image) {
return new Response("Missing image", { status: 400 });
}
if (req.method === "POST") {
const key = "MyFile";
const r2 = await (
fetch(`https://dev_worker.alber.workers.dev/${key}`, {
method: "PUT",
headers: {
"X-CF-Secret": process.env.R2_AUTH_KEY_SECRET as string,
},
body: Uint8Array.from(atob(image.replace(/^data[^,]+,/, "")), (v) =>
v.charCodeAt(0),
),
})
);
return new Response(JSON.stringify({ key }));
} else {
return new Response("Method Not Allowed", { status: 405 });
}
}
` But when I want to download them in my api/image/[id] route, then I simply get an empty object.
import { NextRequest, NextResponse } from "next/server";
export const config = {
runtime: "experimental-edge",
};

export default async function handler(req:NextRequest, res:NextResponse) {
const id = req.nextUrl.searchParams.get("id") as string;
console.log(id)
const url = "https://dev_worker.alber.workers.dev/"+id;
console.log(url)
const object =
fetch(url, {
method: "GET",

//Gets the same result whether I leave the header or not
headers: {
"X-CF-Secret": process.env.R2_AUTH_KEY_SECRET as string,
}
})

console.log("OBJECT"+ JSON.stringify(object))
if (object) {
return new Response(JSON.stringify(object))
} else {
return new Response(null, {
status: 404,
});
}
}
import { NextRequest, NextResponse } from "next/server";
export const config = {
runtime: "experimental-edge",
};

export default async function handler(req:NextRequest, res:NextResponse) {
const id = req.nextUrl.searchParams.get("id") as string;
console.log(id)
const url = "https://dev_worker.alber.workers.dev/"+id;
console.log(url)
const object =
fetch(url, {
method: "GET",

//Gets the same result whether I leave the header or not
headers: {
"X-CF-Secret": process.env.R2_AUTH_KEY_SECRET as string,
}
})

console.log("OBJECT"+ JSON.stringify(object))
if (object) {
return new Response(JSON.stringify(object))
} else {
return new Response(null, {
status: 404,
});
}
}
If I make a get request to the same URL from the cloudflare page, I actually get the image how I am supposed to. What am i doing wrong with my request?
5 Replies
Chaika
Chaika2y ago
Looks like you might be missing the await on the fetch for the image
Alex from Fuxam
Alex from FuxamOP2y ago
I just added an await there and I'm still getting the same {}
Chaika
Chaika2y ago
That endpoint responds with an image, and you're trying to treat it as JSON?
Alex from Fuxam
Alex from FuxamOP2y ago
I was under the assumption that I'd still be able to print its name with object.name if I've gotten it back. Is that wrong? How would I check whether the image has arrived?
Chaika
Chaika2y ago
Just in case we're talking about different parts, I'm talking about the api/image/[id] route you posted, the last code block. You can't JSON.stringify an image, it'll just throw an error If you want to check if your image succeeded, just check the status code. You can use the response.ok property which returns true if the status code is in the success range of 200-299. You could do something like this, instead
if (object.ok) {
return object;
}
else {
return new Response(null, {
status: 404,
});
}
if (object.ok) {
return object;
}
else {
return new Response(null, {
status: 404,
});
}
Which would change your code to something like this:
export default async function handler(req:NextRequest, res:NextResponse) {
const id = req.nextUrl.searchParams.get("id") as string;
console.log(id)
const url = "https://dev_worker.alber.workers.dev/"+id;
console.log(url)
const object =
await fetch(url, {
method: "GET",
//Gets the same result whether I leave the header or not
headers: {
"X-CF-Secret": process.env.R2_AUTH_KEY_SECRET as string,
}
})


if (object.ok) {
return object; // The object is a response
} else {
return new Response(null, {
status: 404,
});
}
}
export default async function handler(req:NextRequest, res:NextResponse) {
const id = req.nextUrl.searchParams.get("id") as string;
console.log(id)
const url = "https://dev_worker.alber.workers.dev/"+id;
console.log(url)
const object =
await fetch(url, {
method: "GET",
//Gets the same result whether I leave the header or not
headers: {
"X-CF-Secret": process.env.R2_AUTH_KEY_SECRET as string,
}
})


if (object.ok) {
return object; // The object is a response
} else {
return new Response(null, {
status: 404,
});
}
}
Should work fine. I tested on workers though not next.js Edit: Thinking about this again, you should probably either respond with the status code it returns (object.status) if not ok, or have a separate check for if the status code is 404 else respond with errors. Always responding with 404 for any non-200 code is probably going to confuse you at some point in the future when you do have a worker problem or something. It looks like you posted and deleted a longer message about an issue with the image. Might be better off asking in the next.js discord (I believe there is one), or reposting it again, as I didn't catch the full thing
Want results from more Discord servers?
Add your server