在Heroku前端部署Angular/Express应用程序时遇到问题,无法命中API端点

laximzn5  于 2023-10-19  发布在  Angular
关注(0)|答案(3)|浏览(175)

目前在开发中,它工作得很好…localhost:4200用于前端,localhost:8080用于后端
然而,我只是部署了它,前端得到显示,但没有从API获取数据,因为在我的app.service.ts中,我正在做以下事情:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  private apiUrl = 'http://localhost:8080/api'

  constructor(private http: HttpClient) { }

  public getNews() {
    return this.http.get(`${this.apiUrl}/countries`)
  }
}

正如你所看到的,我正在硬编码localhost:8080,它在开发中工作得很好,但是当涉及到生产时,Heroku没有分配给我port 8080,它分配给我另一个。
话虽如此...我怎样才能调整它来读取Heroku给我的端口?
这是我的app.js文件

const express = require('express');
const app = express();
const scrapper = require('./backend/scrapper')

// Create link to Angular build directory
var distDir = __dirname + "/dist/covid19";
app.use(express.static(distDir));

app.use((req, res, next) => {
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    );
    res.setHeader(
        "Access-Control-Allow-Methods",
        "GET, POST, PATCH, PUT, DELETE, OPTIONS"
    );
    next();
});

app.use("/api/countries", async (req, res, next) => {
    const data = await scrapper.getCountries()
    res.status(200).json(data)
})

const port = process.env.PORT || 8080;
app.listen(port, () => {
    console.log(`API listening on port ${port}...`);
});

module.exports = app;

正如你所看到的,我将我的端口声明为process.env.PORT || 8080,但这是用于后端的。如何才能实现这一点,但在我的API调用的service.ts文件?

kx1ctssn

kx1ctssn1#

你们给我指出了正确的方向,但准确地说:
我注意到,在Angular中,你会得到一个environments文件夹,其中有两个文件1。environment.tsenvironment.prod.ts
在部署yourappname.herokuapp.com后,我必须确保使用指向Heroku为我的应用程序提供的URL,通过在我的environments.prod.ts中执行以下操作(Heroku将查找的URL)

export const environment = {
  production: true,
  apiUrl: "https://yourappname.herokuapp.com/api"
};

在我的api.service.ts中,我最终得到了以下代码:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../environments/environment'

const API_URL = environment.apiUrl;

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private http: HttpClient) { }

  public getNews() {
    return this.http.get(API_URL + '/countries')
  }
}
kcwpcxri

kcwpcxri2#

当你在Heroku上部署一个Web服务器时,你会绑定到Heroku告诉你要绑定的$PORT
当您访问已部署的应用时,无需指定端口。您只需连接到yourappname.heroku.com。DNS会自动将其转换为ipaddress:port
所以在你的前端,你只需指向yourappname.heroku.com而不是ipaddress:port

zysjyyx4

zysjyyx43#

在部署应用程序时,您必须参考生产变量。我喜欢使用'@angular/core'包中包含的isDevMode函数。

import { isDevMode } from '@angular/core';

setUrl(){
 if(isDevMode() == true){
 //in development mode
 api_url = "localhost:4200"
 }else{
 api_url = "heroku.app_url.app"
 }
}

这个函数让你知道应用程序运行的模式,这样你就可以使用它在连接字符串之间切换。

相关问题