Closed folamy closed 1 year ago
Idk maybe multer or formidable would work
import * as formidable from 'formidable'
import { createApp } from 'h3'
const form = formidable({ multiples: true })
app.use('/upload', async (req, res) => {
form.parse(req, (err, fields, files) => {
// do something
})
// return
});
Idk maybe multer or formidable would work
import * as formidable from 'formidable' import { createApp } from 'h3' const form = formidable({ multiples: true }) app.use('/upload', async (req, res) => { form.parse(req, (err, fields, files) => { // do something }) // return });
I am not sure of this would work either. I believe you are trying to create a new instance of h3 app that is different from nuxt3 server!
Sorry, I forgot to mention that I am using nuxt 3!
Then do it like this?
import type { IncomingMessage, ServerResponse } from 'http'
const form = formidable({ multiples: true })
export default async (req: IncomingMessage, res: ServerResponse) => {
form.parse(req, (err, fields, files) => {
// do something
})
// return
}
Thanks, I will try that and let you know the outcome.
Then do it like this?
import type { IncomingMessage, ServerResponse } from 'http' const form = formidable({ multiples: true }) export default async (req: IncomingMessage, res: ServerResponse) => { form.parse(req, (err, fields, files) => { // do something }) // return }
@wobsoriano, do you know how I can integrate socketio with nuxt3? My major challenge is that I don't have access to the main server instance.
Not sure about this but you can try
// server/middleware/socket.ts
import type { IncomingMessage, ServerResponse } from 'http'
import { Server } from 'socket.io'
let server: any = null
export default (req: IncomingMessage, res: ServerResponse) => {
if (!server) {
// @ts-expect-error: Nuxt3
server = res.socket?.server
const io = new Server(server);
io.on('connection', (socket) => {
console.log('Made socket connection');
socket.on('msg', (msg) => {
console.log('Recived: ' + msg)
setTimeout(() => {
socket.emit('msg', `Response to: ${msg}`)
}, 1000)
})
socket.on('disconnect', () => console.log('disconnected'))
})
}
}
Edit: Tried this, works :)
https://gist.github.com/wobsoriano/79fa3be004f0a1b70f94e34dfbade897
How are you guys sending the data from client? I've been trying to get a image file to transfer to the server side and I'm just not getting it there. I'm not sure what I'm missing
How are you guys sending the data from client? I've been trying to get a image file to transfer to the server side and I'm just not getting it there. I'm not sure what I'm missing
Using https://developer.mozilla.org/en-US/docs/Web/API/FormData
@wobsoriano Thank you, I found that earlier so it's good to hear I'm on the right track. Here is my current setup
Client
const fd = new FormData();
fd.append("name", fileName);
fd.append("image", file);
axios.post("/api/avatars", fd, {
headers: {
'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
'Content-Type': `multipart/form-data; boundary=${file._boundary}`,
}
}).then(resp => { console.log(resp)});
Nuxt3 server/api/avatars
import {IncomingMessage, ServerResponse} from "http";
import formidable from "formidable";
const form = new formidable.IncomingForm();
export default async (req: IncomingMessage, res: ServerResponse) => {
form.parse(req, async (err, fields, files) => {
console.log(err);
console.log(fields);
console.log(files);
})
res.end("Got data");
}
The error I'm getting now is
ERROR [proxy] write EPIPE
at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:98:16)
I'd appreciate your continue help as I've been stuck on this for a day and a half now.
Thank you
The last comment was left back 4 months ago, but @bfg-coding this happened to me too today. What I noticed in the document from Fromdable was they wrapped the form parse function in the promises.
Without it, that's what I encountered
ERROR [proxy] write EPIPE
at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:98:16)
So the final code should be :
export default async (req, res) => {
const form = formidable({ multiples: true });
await new Promise((resolve, reject) => {
form.parse(req, (err, fields, files) => {
console.log(files]
});
});
return {}
}
And I get this:
{
image: [
PersistentFile {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
lastModifiedDate: 2022-03-16T14:56:34.284Z,
filepath: '/var/folders/93/m7bwg2ds5gzf4w35bctsb1k40000gn/T/eff7ead095d57e3ed63a44900',
newFilename: 'eff7ead095d57e3ed63a44900',
originalFilename: '1.jpeg',
mimetype: 'image/jpeg',
hashAlgorithm: false,
size: 317210,
_writeStream: [WriteStream],
hash: null,
[Symbol(kCapture)]: false
}
]
}
Hope this helps some newbies like me guide to the backend world of node frameworks.
Partially related, but how do you guys serve the uploaded file using h3
handler?
I'm trying:
// server/api/file.ts
import type { ServerResponse } from "http";
import { CompatibilityEvent } from "h3";
import fs from "fs";
export default async (event: CompatibilityEvent, res: ServerResponse) => {
const filename = "./uploads/file.jpg";
const readStream = fs.createReadStream(filename);
readStream.on("error", function (err) {
console.log(`error: ${err.message}`);
res.end(err.message);
});
readStream.on("open", function () {
res.statusCode = 200;
readStream.pipe(res);
});
};
But it gives 404 error:
{
"url": "/api/file",
"statusCode": 404,
"statusMessage": "Not Found",
"message": "Not Found"
}
Also asked at Nuxt 3
https://github.com/nuxt/framework/discussions/4299 and found similar question at h3
https://github.com/unjs/h3/issues/93
I am using this inside my /api/media/[id].get.ts
:
import fs from 'fs'
import { sendStream } from 'h3'
import { getFilepathFromId } from '~/server/lib/fileStorage'
export default defineEventHandler(async (event) => {
const fileId = event.context.params.id
const filepath = getFilepathFromId(fileId)
return sendStream(event, fs.createReadStream(filepath))
})
I assumes the fileId
exists in every case :)
It works perfectly except for Safari video streaming that I am currently debugging.
Here's a tangential tutorial that is helpful: https://blog.replit.com/build-a-speech-to-text-app-with-assemblyai-on-replit
For everyone refering to this issue, I actually had to remove the content-type header on the Client to make this work. Otherwise this happened: https://stackoverflow.com/questions/41138443/multipartparser-end-stream-ended-unexpectedly
So the updated Client example would be:
const fd = new FormData();
fd.append("name", fileName);
fd.append("image", file);
axios.post("/api/avatars", fd, {
headers: {
'accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.8',
}
}).then(resp => { console.log(resp)});
How do I use h3 to get files from client/browser for file upload? I am coming from ExpressJs, where I can install a package called express-fileupload. Link: Express Fileupload
How do I achieve this?