- 已解决/请参阅我自己的答案,以获取更多信息 *
嘿,我得到了这个非常奇怪的错误,我似乎无法弄清楚它。所以基本上我试图发送一个音频记录,用户记录在我的Nextjs前端,到我的Nextjs API。这似乎是顺利的。但是,当我试图转发整个录音从我的Nextjs API到我的实际后端端点,这是运行节点/Node. js在Vercel上,我得到了一个405错误的请求。有什么想法吗?
重要提示:在localhost上一切正常。但当我在Vercel上将其投入生产时就不正常了。(客户端和服务器端都是在Vercel上运行的Node应用。一个是Nextjs,一个稍旧的版本,服务器端是Express)
出于安全原因,我使用Next.js作为中间的API
到目前为止,我唯一的理论是“formData.append”不能正常工作,因为每当我试图将其或其全部内容记录出来时,我总是得到一个空白对象:{}
这里:
const formDataToSend = new FormData()
formDataToSend.append(fileName, new Blob([readResult], { type: 'audio/wav' }), `${fileName}.wav`)
字符串
(full代码如下所示)
Nextjs version:13.5.4 Nextjs version:4.18.2
EXPRESS.JS代码:
app.use(cors())
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/')
},
filename: function (req, file, cb) {
cb(null, `${file.originalname}`)
}
})
const upload = multer({ storage: storage })
...
app.post('/upload', [requireSession, upload.any()], async (req, res) =>
{
// the request never even gets here in the first place
// requireSession works fine
})
型
NEXT.JS API:
import { csrf } from '../../../../lib/csrf'
import axios from 'axios'
import crypto from 'crypto'
import multiparty from 'multiparty'
import fs from 'fs'
// valid url
const ENDPOINT_URL = 'https://my-api.com/upload'
// works fine
async function readAudioFile(filePath) {
return new Promise((resolve, reject) => {
const readStream = fs.createReadStream(filePath)
const chunks = []
readStream.on('data', (chunk) => {
chunks.push(chunk)
})
readStream.on('end', () => {
const fileBuffer = Buffer.concat(chunks)
resolve(fileBuffer)
})
readStream.on('error', (err) => {
reject(err)
})
})
}
async function post(req, res)
{
try {
// works fine
const form = new multiparty.Form()
// works fine
const formData = await new Promise((resolve, reject) => {
form.parse(req, function (err, fields, files) {
if (err) reject({ err })
resolve({ fields, files })
})
})
// works fine
const readResult = await readAudioFile(formData.files.audio[0].path)
// works fine
const randomizer = `${req?.headers?._uuid}-${req?.query?.taskId}-${(new Date().getTime()).toString(16)}`
// works fine
const fileName = crypto.createHash('sha256').update(randomizer).digest('hex')
// works fine
const formDataToSend = new FormData()
// !! Not sure. when i log em out, "formDataToSend" and "formDataToSend.entries()" are both empty. (Just a "{}")
formDataToSend.append(fileName, new Blob([readResult], { type: 'audio/wav' }), `${fileName}.wav`)
// Nothing undefined here, works fine
const headers = {
'client': process.env.API_ACCESS_KEY,
'_session': req.headers._session,
'_uuid': req.headers._uuid,
...req.headers,
'Content-Type': 'multipart/form-data',
'Request-Index': '0' ,
}
// this request fails with code 405
await axios.post(ENDPOINT_URL, formDataToSend, { headers, params: { ...req.query } })
.then(response => (res.status(200).json(response.data)))
.catch(error => (console.log(error), res.status(500).json({
...getErrorMessage(),
errorDetails: error,
dataToSend
})))
}
catch (error) {
console.log(error)
res.status(501).json({
...getErrorMessage(),
errorDetails: error,
dataToSend
})
}
}
async function handler(req, res)
{
switch (req.method.toLowerCase())
{
case 'post':
await post(req, res)
break
default:
res.status(200).send(`Method ${req.method} is not allowed.`)
break
}
}
const getErrorMessage = () => { return { time: Date.now(), result: false, status: 500, message: 'Something went wrong' } }
export default csrf(handler)
export const config = {
api: {
bodyParser: false
}
}
型
我已经尝试了几乎所有我能想到的方法。包括使用fetch而不是axios,扰乱我express.js端点的CORS设置等。我认为问题出在FormData上。不过在localhost上运行良好
3条答案
按热度按时间vmjh9lq91#
既然Vercel是无服务器计算提供商,我认为你应该尝试将你的Web应用程序部署到其他平台上。
您也可以阅读:https://vercel.com/guides/using-express-with-vercel
如果成功了告诉我。
4c8rllxm2#
谢谢你们的帮助。我是这样解决的:
改变了这个:
字符串
对此:
型
显然我忘了删除一行干扰请求头的代码。在浪费了几个晚上试图让这件事工作后,我才意识到这是怎么回事。我真傻!
lmyy7pcs3#
换了这个试试
字符串
本
型