[英]Axios api post request returns HTML instead of JSON in production(GAE) (reactjs + express)
我正在使用 reactjs 和 express 服務器並將我的應用程序部署到 Google App Engine。
在開發方面,我可以成功獲得 JSON 格式的 API 響應,但在部署到 GAE 后,我只能獲得一些默認的 HTML 作為響應。
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./nectai.jpg"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta name="theme-color" content="#000000"/><meta name="description" content="ABCD"/><link rel="apple-touch-icon" href="./nectai.jpg"/><link rel="manifest" href="./manifest.json"/><title>ABCD</title><script defer="defer" src="./static/js/main.7a273cc2.js"></script><link href="./static/css/main.4fa4d373.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
我嘗試比較網絡選項卡中的 API 狀態。 (下面的截圖)。 我注意到響應 Header 是不同的(或者更確切地說,在生產端發出的 API 請求中缺少一些標頭)
我確認 API 請求也適用於 postman。
我哪里錯了? 請幫我
server.js
const express = require("express");
const { Buffer } = require("buffer");
const app = express();
const path = require("path");
var cors = require("cors");
const bodyParser = require("body-parser");
const https = require("https");
const axios = require("axios");
const fs = require("fs");
const { Storage } = require("@google-cloud/storage");
if (process.env.NODE_ENV !== "production") {
require("dotenv").config();
}
const port = process.env.PORT || 5000;
console.log("Inside server.js >>> listening on PORT", port);
app.use(bodyParser.json());
app.use(express.json());
app.use(cors({ origin: "*", credentials: true, methods: ['GET','POST','DELETE','UPDATE','PUT','PATCH']}));
app.post("/set", (req, res) => {
const httpsAgent = new https.Agent({
ca: process.env.REACT_APP_CERT,
cert: process.env.REACT_APP_CERT,
key: process.env.REACT_APP_KEY,
});
try {
const instance = axios.create({
httpsAgent,
});
const options = {
url: process.env.REACT_APP_PRED,
method: "POST",
credentials:"include",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,PATCH,OPTIONS",
},
data: {
w: req.body.w,
h: req.body.h,
g: req.body.g,
a: req.body.a,
i: req.body.i,
m: req.body.m,
},
};
instance(options)
.then(async (response) => {
res.json(response.data);
})
.catch((err) => res.send(err));
} catch (err) {
console.error("GG", err);
}
});
if (process.env.NODE_ENV === "production") {
//const path = require('path');
app.get("/", (req, res) => {
console.log("serving static index.html file.. >>");
app.use(express.static(path.resolve(__dirname, "build"))); // using middleware
res.sendFile(path.resolve(__dirname, "build", "index.html")); // serving the static file
});
}
app.listen(port, () => console.log(`app listening on port ${port}!`));
module.exports = app;
frontend-side API request(reactjs)
async function req(postdata) {
const instance = axios.create({});
const options = {
url: "/set",
method: "POST",
credentials:"include",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials':true,
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},
data: postdata,
};
const data = instance(options)
.then(async (response) => {
return response.data;
})
.catch((e) => {
console.log("通信に失敗しました:", e);
});
//return requ;
return data;
}
Network Tab screenshots
Development
Production
另外,在package.json
中,我添加了這一行,這似乎僅在本地環境中對 api 請求有效。
"proxy": "http://localhost:5000"
我設法弄清楚了這個問題。
由於問題出在生產端,我正在查看僅出於生產目的上傳到 GCP 的文件。 一個這樣的文件是app.yaml
。
我在app.yaml
文件中設置的配置(通過從互聯網上的其他地方盲目復制粘貼內容😅)如下。
runtime: nodejs16
handlers:
# Serve all static files with url ending with a file extension
- url: /(.*\..+)$
static_files: build/\1
upload: build/(.*\..+)$
# Catch all handler to index.html
- url: /.*
static_files: build/index.html
upload: build/index.html
secure: always
redirect_http_response_code: 301
includes:
- credentials.yaml
This part url: /.*
meant that any request being sent will fallback to index.html
by default and that was why I had received HTML as the response upon calling the API
所以,我不得不像下面這樣更改配置文件。 (從url: /.*
)
runtime: nodejs16
handlers:
# Serve all static files with url ending with a file extension
- url: /(.*\..+)$
static_files: build/\1
upload: build/(.*\..+)$
# Catch all handler to index.html
- url: /.
static_files: build/index.html
upload: build/index.html
secure: always
redirect_http_response_code: 301
includes:
- credentials.yaml
這為我解決了這個問題😉
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.