Open rafaellucio opened 2 months ago
This issue does not seem to follow the issue template. Make sure you provide all the required information.
Hey @rafaellucio, thanks for the detailed report. I was able to reproduce the issue you mentioned. Just to note, one thing I tried is to create a simple POST api and I was able to get it working:
// api/test.ts
import type { APIContext } from "astro";
export async function POST({ request }: APIContext) {
console.log(" --- api/test POST --- ");
const body = await request.json();
return new Response(
JSON.stringify({
email: body.email,
password: body.password,
status: "ok",
})
);
}
export async function GET({ request }: APIContext) {
return new Response(
JSON.stringify({
name: "Astro",
url: "https://astro.build/",
})
);
}
It seems like the error starts occurring on const formData = await request.formData();
.
Let me raise this to our engineering team so they can take a look. I created this mcve using the information provided.
Yes @aalej, my intent is use default behavior in Astro when I implemente an formulary
Basically add a simple form like this:
<form action="/api/test" method="POST">
<input name="user" />
<input name="pass" />
<button>submit</button>
</form>
When I use Astro the content type of the request context receives an application/x-www-form-urlencoded
and to obtain these values I need to parse my request to FormData using request.formData()
as request .json ( )
and added a new method in the request context called formData
My workarround was create an Astro middleware and use the busboy library to obtain values from request, like this
import { defineMiddleware } from 'astro:middleware';
import Busboy from 'busboy';
const getFieldsFromFormData = (headers: any, body: any) =>
new Promise(async (resolve) => {
const busboy = Busboy({ headers });
let fields: any = {};
busboy.on('field', (field: string, val: any) => {
fields = JSON.parse(field);
});
busboy.on('finish', () => resolve(fields));
busboy.end(body);
});
export const formBody = defineMiddleware(async (context, next) => {
const req = context.request.clone();
const headers = Object.fromEntries(req.headers);
if (
req.method === 'POST' &&
req.headers.get('content-type') === 'application/x-www-form-urlencoded'
) {
try {
const text = await req.text();
const fields: any = await getFieldsFromFormData(headers, text);
context.request.formData = async function () {
return {
...fields,
get: (key: string) => fields[key] ?? '',
};
};
} catch (err) {
console.error(err);
}
}
return next();
});
This works but it's a really bad solution 😢
Maybe this behavior can be add here firebase-frameworks-tools/astro
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
I receibe this message when I deploy my app
[ERROR] TypeError: Error: Unexpected end of multipart data
, following this documentation https://docs.astro.build/en/recipes/build-forms-api/#recipeToday I use the standalone node setup in astro.config.mjs
This is my API test
After call GET this works, but post doesn't works
The log em Google Cloud Function is:
[ERROR] TypeError: Error: Unexpected end of multipart data
What's the expected result?
Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-ao77yt?file=src%2Fpages%2Findex.astro,src%2Fpages%2Fapi%2Flogin.ts,package.json
This error is very very strange, because when I run build and run locally
❯ node dist/server/entry.mjs
Works!!, But after deploy doesn't works
I use this actions to deploy my app in gcloud https://github.com/FirebaseExtended/action-hosting-deploy
Another same issue https://github.com/withastro/astro/issues/10870