Closed wqcstrong closed 5 months ago
I'm having the same problem as well
@kwhitley Any advice to help to fix the issue?
Hey guys - I'm looking into this, but that's def not an itty error (which emits no useful errors because those cost bytes). I'm guessing CF introduced some sort of Fetcher interface check, so I just need to figure what the signature is, and where this code doesn't align :)
@kwhitley Thanks for looking into this! I found that Cloudflare's itty-router-openapi supports their weird fetcher problem.
@wqcstrong In the short term, I've switched to using Cloudflare's itty-router-openapi. It looks like:
import { OpenAPIRouter } from '@cloudflare/itty-router-openapi'
import { getAssetFromKV } from '@cloudflare/kv-asset-handler';
import manifestJSON from '__STATIC_CONTENT_MANIFEST';
const assetManifest = JSON.parse(manifestJSON);
const router = OpenAPIRouter()
router.get("*", serverStaticAsset)
export default {
fetch: router.handle,
}
async function serverStaticAsset(request, env, ctx) {
try {
return await getAssetFromKV({
request,
waitUntil: ctx.waitUntil.bind(ctx),
}, {
ASSET_NAMESPACE: env.__STATIC_CONTENT,
ASSET_MANIFEST: assetManifest,
});
} catch (e) {
return new Response("Resource not found", {
status: 404,
headers: { 'Content-Type': 'text/html' },
})
}
}
@C1ARKGABLE Thanks for your advice, now my solution like this:
export defaut {
async fetch(request: Request, env: Env, ctx: any) {
const url = new URL(request.url);
if (url.pathname.startsWith('/public')) {
try {
return await getAssetFromKV(
{
request,
waitUntil: ctx.waitUntil.bind(ctx),
},
{
ASSET_NAMESPACE: env.__STATIC_CONTENT,
ASSET_MANIFEST: assetManifest,
mapRequestToAsset: () => {
const removePrefix = url.pathname.replace(/^\/public/, '');
const newPath = `${url.origin}${removePrefix}`;
return mapRequestToAsset(new Request(newPath, request));
},
}
);
} catch (e: any) {
const { pathname } = new URL(request.url);
if (e instanceof NotFoundError) {
return text(`"${pathname}" not found`, {
status: 404,
});
} else if (e instanceof MethodNotAllowedError) {
return text(`Method not allowed`, {
status: 400,
});
} else {
return text(`内部异常: ${e.message}`, { status: 500 });
}
}
} else {
return router.fetch(request, env, ctx);
}
},
}
cloudflare changed the request.fecth
property after 2024-04-03, so if you set the compatibility_date
in wrangler.toml
prior to that date, it works fine.
the work around is to just create a new request
object to pass to to getAssetFromKV
return await getAssetFromKV(
{
request: new Request(request.url, { ...request }),
waitUntil: ctx.waitUntil.bind(ctx),
},
{
ASSET_NAMESPACE: env.__STATIC_CONTENT,
ASSET_MANIFEST: assetManifest,
},
)
As for the nested route problem, you just have to replace the path
const router = AutoRouter()
const kvAssetsMiddleware = (basePath: string) => {
const middleware: RequestHandler = async (request, env, ctx) => {
const url = new URL(request.url)
url.pathname = url.pathname.replace(new RegExp(String.raw`^${basePath}`), '')
return await getAssetFromKV(
{
request: new Request(url, { ...request }),
waitUntil: ctx.waitUntil.bind(ctx),
},
{
ASSET_NAMESPACE: env.__STATIC_CONTENT,
ASSET_MANIFEST: assetManifest,
},
)
}
return middleware
}
router.all('*', kvAssetsMiddleware('/dist'))
Describe the Issue
I'm following the Worker Sites - Start from worker guide to intergate the KV namespace for static assets, after that my project looks like this:
Above is all code, then I test in the local and I got the error:
Expected Behavior
The
curl http://localhost:8787/public/img/logo.svg
return a normal success responseActual Behavior
It throw an error:
Incorrect type for the 'fetcher' field on 'RequestInitializerDict': the provided value is not of type 'Fetcher'.
Environment (please complete the following information):