Heroku将Angular调用代理到后端API的正确方法是什么?

问题描述 投票:0回答:1

注:2019年6月更新; 见下文

这不是关于特定代码片段的问题; 相反,我正在寻求帮助,为使用MEAN堆栈(MongoDB,Express,Angular,Node)与后端API进行通信的Angular客户端正确构建代理。 我是一名老学校的C程序员,他自学了自己的意思。 老狗,新的把戏。 我已经清理了几个资源,包括Stack Overflow,但我还没有找到答案。 Stack Overflow上的几个用户报告了同样的问题(我在SOURCES下列出了这些问题)。 我还有Heroku的帮助票。

感谢所有阅读此内容并考虑它的人。 特别感谢所有发布有用建议和解决方案的人(提前)。

问题:如何正确构建Angular客户端对后端API的调用以避免CORS(跨源资源共享)中固有的问题? 我从Angular文档代理中提取并开发的解决方案在我的开发系统(即localhost)上运行时可以正常工作,但在上传到我的PaaS(Heroku)时失败了。 这是因为Angular的代理是仅用于开发的工具吗? 如果是这样,调用后端API的正确方法是什么?

配置:我正在开发Darwin OS(macOS 10.14.4),使用Node 10.13.0,npm 6.9.0,Express 4.16.2和Angular 7.2.9。 我正在Bitbucket上使用git存储库,它将部署管道传输到Heroku。 我为客户端(Angular)和API(Node / Express)分别进行了部署。 现在,客户端正在运行Hobby dyno和Heroku上的免费dyno上的API。 我的数据库托管在Sandbox(免费数据库)中的mLab上。 客户: https//www.markwilx.com API: http//markwilx-api.herokuapp.com/api/test

讨论:Stack Overflow中的以下问题与我遇到的问题相同: Angular proxy.conf.json调用API在本地工作但不在Heroku上没有给出解决方案,但Massimiliano Sartoretto发表评论说:“该代理是应该只适用于开发服务器。 它与Heroku无关,甚至不应该部署在Heroku上。 它的目标是帮助您在从localhost提供应用程序时代理外部API调用“我对此评论有疑问。 官方的Angular文档(参见下面的SOURCES)没有提到这一点。 我并没有质疑Sartoretto先生的主张,但我当然断言他的主张并不广为人知,也没有记录。 如果有人知道这个事实,我会很感激参考,我可以阅读它。

同样,使用相同方法的Chenkie先生在他的书中没有提到这一点(参见下面的资料)。 几个月来我曾多次尝试通过他的网站向陈基先生询问,但他没有回应。 如果他/如果他这样做,我会更新这篇文章。

Heroku的优秀团队已经回复了我的帮助票。 Heroku不提供本机代理功能,因此必须在Angular客户端中处理任何代理。 他们倾向于认为问题出在Sartoretto先生声称的范围内。 当然,描述我应该如何构建我的客户端和API是在他们的服务范围之外。

最后,我在Heroku上使用Node.js在Stack Overflow Proxy服务器上找到了以下内容。这也是我遇到的同样问题。 问这个问题的人Andrea Reginato没有使用Angular,但是他发布了他的Node解决方案。 我想知道这是否是首选方法,我只需将其移植到Angular中。

我真的被卡住了,我想确保用行业最佳实践技术构建我的系统。

来源:有关配置代理到后端服务器的官方Angular文档,请访问以下链接: https//angular.io/guide/build#proxying-to-a-backend-server

我一直在阅读和关注Ryan Chenkie的“确保角度应用”。 从第41页开始,他开始演示如何为其示例应用程序构建代理。 他的例子与上述Angular文档中的方法一致。

以下是Stack Overflow上未解决的与我遇到的问题密切相关的查询:

[我不得不删除所有这些。 包含它们,Stack Overflow决定我的帖子是垃圾邮件。 我把最重要的内容放在上面的文字中。


更新:2019年6月04日

我继续研究这个问题但收效甚微。 虽然我发现除了Massimiliano Sartoretto的评论之外什么都没有说明代理只适用于开发服务器,我已经删除了代理,并试图通过其他方式解决外部API问题。

目前,我已经配置了内容安全策略来解决跨源资源共享问题,我使用Express使用以下代码重定向API调用:

    app.get('/api/test', function(req, res) {
      request.get({
        url: 'https://markwilx-api.herokuapp.com/api/test' 
      }, function(error, response, body) {
        if(!error && response.statusCode == 200) {
          res.send(body);
        }
      });
    });

再次,这在我的开发环境(在localhost上运行的前端服务器和在Heroku上运行的后端服务器)上无缝地工作,但是一旦上传到Heroku就失败了。

在调用API时,在Heroku上运行的前端服务器会出现以下错误:

Jun 04 05:08:02 markwilx heroku/router: at=info method=GET path="/api/test" host=www.markwilx.com request_id=2f789dad-7161-4269-bf92-64db8060eadd fwd="184.170.243.167" dyno=web.1 connect=0ms service=10ms status=500 bytes=404 protocol=https 
Jun 04 05:08:02 markwilx app/web.1: ReferenceError: request is not defined 
Jun 04 05:08:02 markwilx app/web.1:     at /app/server.js:35:3 
Jun 04 05:08:02 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
Jun 04 05:08:02 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/route.js:137:13) 
Jun 04 05:08:02 markwilx app/web.1:     at Route.dispatch (/app/node_modules/express/lib/router/route.js:112:3) 
Jun 04 05:08:02 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
Jun 04 05:08:02 markwilx app/web.1:     at /app/node_modules/express/lib/router/index.js:281:22 
Jun 04 05:08:02 markwilx app/web.1:     at Function.process_params (/app/node_modules/express/lib/router/index.js:335:12) 
Jun 04 05:08:02 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/index.js:275:10) 
Jun 04 05:08:02 markwilx app/web.1:     at SendStream.error (/app/node_modules/serve-static/index.js:121:7) 
Jun 04 05:08:02 markwilx app/web.1:     at emitOne (events.js:116:13) 
Jun 04 05:08:07 markwilx heroku/router: at=info method=GET path="/api/test" host=www.markwilx.com request_id=99922c46-a529-4f7e-8190-670cedf3a33d fwd="184.170.243.167" dyno=web.1 connect=0ms service=5ms status=500 bytes=404 protocol=https 
Jun 04 05:08:07 markwilx app/web.1: ReferenceError: request is not defined 
Jun 04 05:08:07 markwilx app/web.1:     at /app/server.js:35:3 
Jun 04 05:08:07 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
Jun 04 05:08:07 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/route.js:137:13) 
Jun 04 05:08:07 markwilx app/web.1:     at Route.dispatch (/app/node_modules/express/lib/router/route.js:112:3) 
Jun 04 05:08:07 markwilx app/web.1:     at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 
Jun 04 05:08:07 markwilx app/web.1:     at /app/node_modules/express/lib/router/index.js:281:22 
Jun 04 05:08:07 markwilx app/web.1:     at Function.process_params (/app/node_modules/express/lib/router/index.js:335:12) 
Jun 04 05:08:07 markwilx app/web.1:     at next (/app/node_modules/express/lib/router/index.js:275:10) 
Jun 04 05:08:07 markwilx app/web.1:     at SendStream.error (/app/node_modules/serve-static/index.js:121:7) 
Jun 04 05:08:07 markwilx app/web.1:     at emitOne (events.js:116:13) 

我将继续提供更新,因为我正在努力解决此问题。

node.js angular express heroku http-proxy
1个回答
0
投票

我没有找到任何确定的答案,但最佳做法似乎是使用CORS(跨源资源共享)。

在他的书“安全角度应用程序”中,Ryan Chenkie指导读者使用代理设置用户注册路由。 在第43页,他说,“差异可能看起来不那么重要,但这种区别使得世界变得不同,并且允许我们绕过诸如跨源资源共享(CORS)之类的东西,并且还使我们能够更容易地设置cookie “。

因此,我避免使用CORS尝试在Heroku上部署我的角度应用程序。 但是,CORS似乎是构建API的行业标准。 似乎Massimiliano Sartoretto声称(见上文)代理不适用于生产环境。 我认为CORS不是一个可以简单地“绕过”并通过其他来源学习CORS的东西。

我多次尝试联系Mr.Chenkie,通过他自己的网站联系页面了解他的方法。 他从不回答。 因此,我觉得我非常失望地说他非常失望,他的书是关于保护角度应用程序 - 表面上是为了部署它们,避免了Web应用程序中的这个基本安全问题。 我不知道他的书中可能还遗漏了哪些其他重要的安全问题; 因此,我不推荐他的书。 去其他地方学习角度应用程序Web安全性。

以下是一些关于CORS的非常有用的解释:

请注意,预检请求(http OPTION)是学习Angular应用程序的重要方面。

npm中有一个有用的CORS包,你可以在这里找到: https//www.npmjs.com/package/cors

祝你的编程好运!

标记

© www.soinside.com 2019 - 2024. All rights reserved.