質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

解決済

heroku でデプロイしたAPIのresponseが htmlで返ってくる Node.js(Express) / React / Typescript / mongodb

shuya-tamaru
shuya-tamaru

総合スコア26

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

1回答

0評価

0クリップ

221閲覧

投稿2022/06/09 07:33

前提

api → node.js (express) + typescript + DB mongodb
frontend → React + typescript
でアプリを作成

api → heroku
frontend → firebase
でデプロイしました。

データベースに保存済みの、データのリストを取得する処理において、本番環境にて問題が発生いたしました。

発生していること

本番環境で、responseがうまく取得できない。

frontendからapiに対して、ユーザーが紐づいているデータのリストを取得するためにrequestを送り、そのresponseのdataは、本来オブジェクトを格納したArray型↓
data: [ { }, { }, { }, .... ] でcontent-type : application/json; 返ってくるはずだったのですが、

以下の様に、

response.data

data: "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"/><link rel=\"icon\" href=\"/favicon.ico\"/><meta name=\"viewport\" content=\"width=device-width,initi .............

といった感じで、content-type: "text/html; でreponseが返ってきてしまい、その後受け取ったデータをmap関数で展開する処理があるので、エラーを吐いてしまいます。

ローカル環境では、問題なくcontent-type : application/json; でArray型が返ってきてました。以下が、本来想定するresponseのdataです。

response.data

[ { "_id": "628c35365b15252e6422c9ee", "name": "ビル名1", "buildingPath": "https://bbbbbbbbb", "userId": [], "companyId": "12345", "createdAt": "2022-05-24T01:30:30.391Z", "updatedAt": "2022-05-24T01:40:26.205Z", "__v": 0 }, { ......省略 }, ]

また、postmanを使用して、デプロイ済みのapiに対してrequestを送ったところ、こちらも問題なくcontent-type : application/json;でarray型が返ってきました。

本番環境においてうまく行かない原因が特定できず苦戦しております。
基本的な内容かもしれませんが、ご教授いただけると幸いです。

実現したいこと

本番環境において、herokuでデプロイしたAPIから、目的とする形式でresponse.dataを受け取りたい。

発生している問題・エラーメッセージ

エラーは発生しておらず、本番環境において、responseの形式が予期せぬものとなってしまっている。

該当のソースコード

API↓

users.ts

import { Router } from "express"; import User from "../models/User"; import Building from "../models/Building"; const router = Router(); ........省略 // get user's all building router.get("/timeline/:id", async (req, res) => { try{ const currentUser = await User.findById(req.params.id); const userBuildings = await Building.find({companyId: currentUser!.companyId}) return res.status(200).json(userBuildings); }catch(err){ return res.status(403).json(err); } }); export default router;

frontend ↓

BuildingList.tsx

import React, { useState, useEffect } from 'react'; import { Link } from 'react-router-dom'; import styled from "styled-components"; import { AiOutlineMore } from 'react-icons/ai'; import axios from "axios"; import IBuilding from "../interface/IBuilding" const BuildingList: React.FC = () => { const HEADERS = { Accept: 'application/json', 'Content-Type': 'application/json' }; const [buildings, setBuildings] = useState<IBuilding[]>([]); useEffect(() => { const fetchBuildings = async () => { const response = await axios.get( ###①ここでAPIにrequest "/users/timeline/62874078c008a45d53c48981",{ headers: HEADERS, } ); setBuildings(response.data); ###②受け取ったresponse.dataをuseStateにセット。ここが本来はArrayだが、本番環境だとhtmlで返ってきてしまう。ローカルは問題なし。postman→deploy済みのAPIへも問題なし。 }; fetchBuildings(); }, []); return ( <SCenter> <span>Building List</span>    ###③buildingsをmap関数で展開。本番環境だとここでエラーを吐いてしまう。ローカルだとちゃんとarray型でresponseが返ってきているので問題なし。 {buildings.map((building)=>( <Sbuilding key={building._id}> <SImage> <Link to={`/building/${building._id}`}> </Link> </SImage> .........以下関係ないので省力します。 </Sbuilding> ) }; .....以下 styled component 省略 export default BuildingList

念のため↓
↓API側

server.ts

import express from "express"; import userRoute from "./routes/users"; import authRoute from "./routes/auth"; import postRoute from "./routes/posts"; import buildingRoute from "./routes/building"; import uploadRoute from "./routes/upload"; import mongoose from 'mongoose'; import 'dotenv/config' // Connect to MongoDB mongoose .connect(`${process.env.MONGOURL}`) .then(() => { console.log("connecting to DB..."); }) .catch((err: unknown) => { console.log(err); }); //middleware const app = express(); const PORT = 5000; app.use(express.json()); app.use("/api/users", userRoute); app.use("/api/auth", authRoute); app.use("/api/posts", postRoute); app.use("/api/buildings", buildingRoute); app.use("/api/upload", uploadRoute); app.listen( process.env.PORT || PORT, () => console.log("running server..."));

試したこと

requestを送る際に、headersで以下を指定してみましたが、特に影響なし。

const HEADERS = { Accept: 'application/json', 'Content-Type': 'application/json' }; const response = await axios.get( "/users/timeline/62874078c008a45d53c48981",{ headers: HEADERS, } );

補足情報(FW/ツールのバージョンなど)

[version]
express : 4.18.1
react : 18.1.0
typescript : 4.7.2

基本的な内容かもしれませんがご教授いただけますと幸いです。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

hoshi-takanori

2022/06/09 09:24

その HTML をブラウザで開いたらエラーメッセージが書いてあるのでは。(DB の接続とかかな…。)
shuya-tamaru

2022/06/09 10:26

コメントありがとうございます。 受け取ったデータを見てみたのですが、以下の様なものでした。 特に、エラーメッセージの様なものはなさそうでした・・・ もう一度、初めからデプロイの手順を見直してみようと思います。 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"/> <link rel="icon" href="/favicon.ico"/> <meta name="viewport" content="width=device-width,initial-scale=1"/> <meta name="theme-color" content="#000000"/> <meta name="description" content="Web site created using create-react-app"/> <link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/> <title>React App</title> <script defer="defer" src="/static/js/main.3c11bf54.js"></script> <link href="/static/css/main.f2a43568.css" rel="stylesheet"> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>
shuya-tamaru

2022/06/09 10:28

ただ、ここの部分が気になるので、調べてみようと思います。 <noscript>You need to enable JavaScript to run this app.</noscript>
hoshi-takanori

2022/06/09 10:41

それは React アプリの index.html ですね。そして、api と react は別のサイトにデプロイしたようですが、それなら axios で API を叩く際には絶対パス (ホスト名か IP アドレスを含む URL) を指定する必要があるのでは。
shuya-tamaru

2022/06/09 10:57

おっしゃる通りでした、非常に基本的な間違いでハマっておりました。 大変お手間おかけいたしました。 ご回答いただき感謝いたします。 ありがとうございました。
shuya-tamaru

2022/06/09 11:01

もしお手間でなければ、回答欄に記載していただきたく、ベストアンサーに選ばせていただきたいと思っております。 お手間でしたら、こちらのやりとりで解決した旨を自己解決にて書かせていただきます。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。