nextjs POSt API 不能在实时环境中工作,但在本地工作完美
nextjs POSt API not working in live environment, but working perfect on local
我最近开始学习使用 Nextjs 构建 Web 应用程序,因此我决定构建一个简单的应用程序来尝试和学习。我在本地开发,一切都运行良好。但是,当我部署到 vercel 时,POST 函数不起作用。
这个app很简单,在首页显示一些数据,还有一个输入新数据的页面——使用prisma SQLite。
从数据库中提取数据在主页上工作正常,但是当我尝试插入数据时,它失败并显示以下错误消息;
Failed to load resource: the server responded with a status of 500 ()
以及
adddata:1 Uncaught (in promise) SyntaxError: Unexpected end of JSON input
它与 ENV 变量没有任何关系,因为我没有在此应用程序上设置任何变量。一切都在我的本地主机上完美运行。请参阅下面的添加数据页面上的代码
import Head from 'next/head'
import { useState } from 'react';
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient();
export default function AddData(props) {
const [formData, setFormData] = useState({})
const [responseMessage, setResponseMessage] = useState()
const [lastEntryMiles, setLastEntryMiles] = useState()
const addLastMillage = () => {
setLastEntryMiles(props.lastEntry.miles);
document.getElementById('lastEntry').focus();
}
async function saveItem(e) {
e.preventDefault()
const response = await fetch('/api/addfuelitem/', {
method: 'POST',
body: JSON.stringify(formData),
})
if(!response.ok){
// throw new Error(response.statusText);
setResponseMessage(response.statusText);
}
if(response.ok){
setResponseMessage("Sucess!!");
window.setTimeout(function(){
window.location.href = "/";
}, 2000);
}
return await response.json()
}
return (
<>
<Head>
<title>Add Data Fuel Tracker</title>
<meta name="description" content="Custom Fuel Tracker" />
</Head>
<section>
<div className="container p-5">
<div className="text-center"><h2>Add Fuel Data</h2></div>
<form onSubmit={saveItem}>
<div className="mb-3">
<label htmlFor="miles" className="form-label">Enter the current millage</label>
<input type="number" className="form-control" id="miles" name="miles" onChange={e => setFormData({ ...formData, miles: +e.target.value })} />
</div>
<div className="mb-3">
<label htmlFor="volume" className="form-label">Enter the volume of fuel</label>
<input type="number"step="0.01" className="form-control" id="volume" name="volume" onChange={e => setFormData({ ...formData, volume: +e.target.value })} />
</div>
<div className="mb-3">
<label htmlFor="cost" className="form-label">Enter the total cost of the fuel</label>
<input type="number"step="0.01" className="form-control" id="cost" name="cost" onChange={e => setFormData({ ...formData, cost: +e.target.value })} />
</div>
<div className="mb-3">
<a className="btn btn-primary" onClick={addLastMillage}>Add Last Millage</a>
</div>
<div className="mb-3">
<label htmlFor="lastEntry" className="form-label">Last Millage</label>
<input type="number" className="form-control" id="lastEntry" name="lastEntry" defaultValue={props.lastEntry.miles} onChange={e => setFormData({ ...formData, lastEntry: +e.target.value })} />
</div>
<div className="mb-3">
<label htmlFor="station" className="form-label">Enter the name of the petrol station (optional)</label>
<input type="text" className="form-control" id="station" placeholder="Enter the name of the petrol station (optional)" name="station" onChange={e => setFormData({ ...formData, station: e.target.value })} />
</div>
<div className="col-12">
<button className="btn btn-primary" type="submit" >Submit form</button>
</div>
<div className="col-12 responseMessage">{ responseMessage }</div>
</form>
</div>
</section>
</>
)
}
export async function getStaticProps(){
const getLastEntry = await prisma.fuelitem.findFirst({
orderBy: {
id: 'asc',
},
take: -1, // Reverse the list
})
return {
props:{
lastEntry:JSON.parse(JSON.stringify(getLastEntry))
}
}
}
下面是 api 页面
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient();
export default async function handler(req, res) {
const data = JSON.parse(req.body)
const costLitre = data.cost / data.volume
const gallons = data.volume * 0.219
const milesTrip = data.miles - data.lastEntry
const mpg = milesTrip / gallons
const savedfuelitem = await prisma.fuelitem.create({
data:{
miles: data.miles,
volume: data.volume,
cost: data.cost,
station: data.station,
costLitre: costLitre,
milesTrip: milesTrip,
mpg: mpg
}
})
res.json(savedfuelitem)
}
编辑以获取更多信息
服务器日志是
[POST] /api/addfuelitem
00:20:39:30
info - Loaded env from /var/task/.env
2021-10-21T23:20:40.899Z 2e81b793-c28e-4ead-9448-411a4e8c11b7 ERROR PrismaClientInitializationError: Error querying the database: unable to open database file: /var/task/node_modules/.prisma/client/./data.db
at cb (/var/task/node_modules/@prisma/client/runtime/index.js:38543:17)
at async handler (/var/task/.next/server/pages/api/addfuelitem.js:26:25)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:101:9)
at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:770:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:661:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:205:32)
at async Server.run (/var/task/node_modules/next/dist/server/next-server.js:841:29)
at async Server.handleRequest (/var/task/node_modules/next/dist/server/next-server.js:292:20)
at async Server.<anonymous> (/var/task/___next_launcher.js:32:9) {
clientVersion: '3.3.0',
errorCode: undefined
}
2021-10-21T23:20:40.899Z 2e81b793-c28e-4ead-9448-411a4e8c11b7 ERROR PrismaClientInitializationError: Error querying the database: unable to open database file: /var/task/node_modules/.prisma/client/./data.db
at cb (/var/task/node_modules/@prisma/client/runtime/index.js:38543:17)
at async handler (/var/task/.next/server/pages/api/addfuelitem.js:26:25)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:101:9)
at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:770:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:661:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:205:32)
at async Server.run (/var/task/node_modules/next/dist/server/next-server.js:841:29)
at async Server.handleRequest (/var/task/node_modules/next/dist/server/next-server.js:292:20)
at async Server.<anonymous> (/var/task/___next_launcher.js:32:9) {
clientVersion: '3.3.0',
errorCode: undefined
}
RequestId: 2e81b793-c28e-4ead-9448-411a4e8c11b7 Error: Runtime exited with error: exit status 1
Runtime.ExitError
但是没有任何响应体,只有响应头是
cache-control: s-maxage=0
content-disposition: inline; filename="500"
content-type: text/html; charset=utf-8
date: Thu, 21 Oct 2021 23:20:41 GMT
server: Vercel
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-matched-path: /500
x-vercel-cache: MISS
x-vercel-id: lhr1::964nh-1634858438937-e662abbca7b4
您正在尝试连接到您的 Vercel 服务器中的 sqlite
database/file。这是不可能的,因为
- 您可能还没有初始化 sqlite 数据库。
- Vercel 在 lambda 中运行 运行,因此它们是非持久性的(您不希望您的数据库这样做)。
我建议切换到托管数据库解决方案(PostgreSQL、MySQL 或 SQL 服务器)。您可以在 Prisma docs.
中找到有关部署到 Vercel 的更多信息
我最近开始学习使用 Nextjs 构建 Web 应用程序,因此我决定构建一个简单的应用程序来尝试和学习。我在本地开发,一切都运行良好。但是,当我部署到 vercel 时,POST 函数不起作用。
这个app很简单,在首页显示一些数据,还有一个输入新数据的页面——使用prisma SQLite。
从数据库中提取数据在主页上工作正常,但是当我尝试插入数据时,它失败并显示以下错误消息;
Failed to load resource: the server responded with a status of 500 ()
以及
adddata:1 Uncaught (in promise) SyntaxError: Unexpected end of JSON input
它与 ENV 变量没有任何关系,因为我没有在此应用程序上设置任何变量。一切都在我的本地主机上完美运行。请参阅下面的添加数据页面上的代码
import Head from 'next/head'
import { useState } from 'react';
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient();
export default function AddData(props) {
const [formData, setFormData] = useState({})
const [responseMessage, setResponseMessage] = useState()
const [lastEntryMiles, setLastEntryMiles] = useState()
const addLastMillage = () => {
setLastEntryMiles(props.lastEntry.miles);
document.getElementById('lastEntry').focus();
}
async function saveItem(e) {
e.preventDefault()
const response = await fetch('/api/addfuelitem/', {
method: 'POST',
body: JSON.stringify(formData),
})
if(!response.ok){
// throw new Error(response.statusText);
setResponseMessage(response.statusText);
}
if(response.ok){
setResponseMessage("Sucess!!");
window.setTimeout(function(){
window.location.href = "/";
}, 2000);
}
return await response.json()
}
return (
<>
<Head>
<title>Add Data Fuel Tracker</title>
<meta name="description" content="Custom Fuel Tracker" />
</Head>
<section>
<div className="container p-5">
<div className="text-center"><h2>Add Fuel Data</h2></div>
<form onSubmit={saveItem}>
<div className="mb-3">
<label htmlFor="miles" className="form-label">Enter the current millage</label>
<input type="number" className="form-control" id="miles" name="miles" onChange={e => setFormData({ ...formData, miles: +e.target.value })} />
</div>
<div className="mb-3">
<label htmlFor="volume" className="form-label">Enter the volume of fuel</label>
<input type="number"step="0.01" className="form-control" id="volume" name="volume" onChange={e => setFormData({ ...formData, volume: +e.target.value })} />
</div>
<div className="mb-3">
<label htmlFor="cost" className="form-label">Enter the total cost of the fuel</label>
<input type="number"step="0.01" className="form-control" id="cost" name="cost" onChange={e => setFormData({ ...formData, cost: +e.target.value })} />
</div>
<div className="mb-3">
<a className="btn btn-primary" onClick={addLastMillage}>Add Last Millage</a>
</div>
<div className="mb-3">
<label htmlFor="lastEntry" className="form-label">Last Millage</label>
<input type="number" className="form-control" id="lastEntry" name="lastEntry" defaultValue={props.lastEntry.miles} onChange={e => setFormData({ ...formData, lastEntry: +e.target.value })} />
</div>
<div className="mb-3">
<label htmlFor="station" className="form-label">Enter the name of the petrol station (optional)</label>
<input type="text" className="form-control" id="station" placeholder="Enter the name of the petrol station (optional)" name="station" onChange={e => setFormData({ ...formData, station: e.target.value })} />
</div>
<div className="col-12">
<button className="btn btn-primary" type="submit" >Submit form</button>
</div>
<div className="col-12 responseMessage">{ responseMessage }</div>
</form>
</div>
</section>
</>
)
}
export async function getStaticProps(){
const getLastEntry = await prisma.fuelitem.findFirst({
orderBy: {
id: 'asc',
},
take: -1, // Reverse the list
})
return {
props:{
lastEntry:JSON.parse(JSON.stringify(getLastEntry))
}
}
}
下面是 api 页面
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient();
export default async function handler(req, res) {
const data = JSON.parse(req.body)
const costLitre = data.cost / data.volume
const gallons = data.volume * 0.219
const milesTrip = data.miles - data.lastEntry
const mpg = milesTrip / gallons
const savedfuelitem = await prisma.fuelitem.create({
data:{
miles: data.miles,
volume: data.volume,
cost: data.cost,
station: data.station,
costLitre: costLitre,
milesTrip: milesTrip,
mpg: mpg
}
})
res.json(savedfuelitem)
}
编辑以获取更多信息
服务器日志是
[POST] /api/addfuelitem
00:20:39:30
info - Loaded env from /var/task/.env
2021-10-21T23:20:40.899Z 2e81b793-c28e-4ead-9448-411a4e8c11b7 ERROR PrismaClientInitializationError: Error querying the database: unable to open database file: /var/task/node_modules/.prisma/client/./data.db
at cb (/var/task/node_modules/@prisma/client/runtime/index.js:38543:17)
at async handler (/var/task/.next/server/pages/api/addfuelitem.js:26:25)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:101:9)
at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:770:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:661:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:205:32)
at async Server.run (/var/task/node_modules/next/dist/server/next-server.js:841:29)
at async Server.handleRequest (/var/task/node_modules/next/dist/server/next-server.js:292:20)
at async Server.<anonymous> (/var/task/___next_launcher.js:32:9) {
clientVersion: '3.3.0',
errorCode: undefined
}
2021-10-21T23:20:40.899Z 2e81b793-c28e-4ead-9448-411a4e8c11b7 ERROR PrismaClientInitializationError: Error querying the database: unable to open database file: /var/task/node_modules/.prisma/client/./data.db
at cb (/var/task/node_modules/@prisma/client/runtime/index.js:38543:17)
at async handler (/var/task/.next/server/pages/api/addfuelitem.js:26:25)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:101:9)
at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:770:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:661:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:205:32)
at async Server.run (/var/task/node_modules/next/dist/server/next-server.js:841:29)
at async Server.handleRequest (/var/task/node_modules/next/dist/server/next-server.js:292:20)
at async Server.<anonymous> (/var/task/___next_launcher.js:32:9) {
clientVersion: '3.3.0',
errorCode: undefined
}
RequestId: 2e81b793-c28e-4ead-9448-411a4e8c11b7 Error: Runtime exited with error: exit status 1
Runtime.ExitError
但是没有任何响应体,只有响应头是
cache-control: s-maxage=0
content-disposition: inline; filename="500"
content-type: text/html; charset=utf-8
date: Thu, 21 Oct 2021 23:20:41 GMT
server: Vercel
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-matched-path: /500
x-vercel-cache: MISS
x-vercel-id: lhr1::964nh-1634858438937-e662abbca7b4
您正在尝试连接到您的 Vercel 服务器中的 sqlite
database/file。这是不可能的,因为
- 您可能还没有初始化 sqlite 数据库。
- Vercel 在 lambda 中运行 运行,因此它们是非持久性的(您不希望您的数据库这样做)。
我建议切换到托管数据库解决方案(PostgreSQL、MySQL 或 SQL 服务器)。您可以在 Prisma docs.
中找到有关部署到 Vercel 的更多信息