簡體   English   中英

Axios api 發布請求返回 HTML 而不是 Z0ECD11C1D7A287401D148A23BBD7actjsE8 快速生產(生產中)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM