node.js - Angular 8:在 Heroku 订阅 observable 时返回 HTML 而不是 json,但在本地运行时不会返回
问题描述
概括
Unexpected token < in JSON at position 0 at JSON.parse
尝试从 Mongo 检索数据时收到错误。相同的代码在 Angular 7 中有效,Angular 8 代码在本地运行时有效,但在部署时无效。
我验证了 express.static 目录、文件结构和 package.json 设置是否正确。该应用程序的所有其他部分都运行良好 - 身份验证、帐户创建、发布新博客、编辑现有博客等。
除了我使用 .subscribe() 检索所有博客文章的页面之外,每个页面都正常显示。我在使用 Angular 7 构建的博客应用程序中有确切的代码,它按预期工作。主要区别是我使用 Heroku 的 Mlab 插件来提供一个数据库来托管数据。当前代码使用 Heroku 本地 Web 运行良好,但是部署后我仍然可以检索和显示单个帖子、登录/退出、创建帖子、创建帐户等,因此数据在 Heroku 和 Mlab 之间流动。
我添加了一个按钮来检索单个文档,它按预期加载,但是通过订阅请求所有文档会引发错误。我花了一整天的时间试图弄清楚这一点无济于事。
代码:Express/Node.js & Typescript/Angular 8
这是提供静态文件的地方 - 尝试使用
__dirname
和不使用 Node.js:
app.use(express.static('dist'));
// var distDir = __dirname + "/dist/";
// app.use(express.static(distDir));
这是路由的服务器端:
router.route('/blog').get((req, res) =>{
console.log('Blog route called');
BlogPost.find((err, allPosts) => {
if(err){
console.log('Error' + err);
throw new Error('Unable to load blog posts');
} else {
console.log(" All posts data: " + allPosts);
res.json(allPosts);
}
});
BlogPost 是一种猫鼬模型,在其他任何地方使用它都没有问题。
这是来自服务的代码:
//calls the server with a GET method
getBlog(){
console.log("Blog service")
return this.http.get(`/blog`, {withCredentials: true});
}
这是组件的初始调用:
getAllPosts(){
console.log("Get All called");
this.blogService
.getBlog()
.subscribe((data: BlogPost) => {
this.allBlogPosts = data.reverse();
console.log("Data Requested...");
});
}
结果
实际结果:app模块加载,但是页面是空白的,控制台显示错误。
错误是和 HttpResponse 错误:error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad
部分错误消息包括:text: "<!doctype html>↵<html lang="en">↵<head>↵ <meta charset="utf-8">↵ <title>Blog</title>↵ <base href="/">↵↵ <meta name="viewport" content="width=d ...
这是来自 index.html 文件。这是否意味着返回的是文件而不是 Mlab 文档?
当使用 Heroku 的插件配置 MLab 数据库时,完全相同的代码可以工作,这一事实让我认为这可能不是我的代码特别有问题,但我欢迎任何建议。我可能最终会重构这个,因为如果我不需要的话,我宁愿不使用 Heroku 的插件(而且我不明白为什么这会有所不同)
编辑
它与我如何在 Angular 中设置路由或 Heroku 如何处理它有关,因为它在本地工作。
现在我有根重定向到 /blog 查询服务器并将每个帖子发送到前端,这导致了配对错误。
我添加了一个静态登录页面,然后链接到一个新创建的博客/所有路由,该路由查询并发送所有帖子,并且数据传递时没有错误。
有人知道这是为什么吗?
解决方案
好的,所以我能够想出一个相对简单的解决方案,但是我不能确切地说为什么我发布的代码在本地工作而不是在 Heroku 上工作,但我确实有一个理论。
根本原因
为 DB 数据服务的后端路由与为 index.html 服务的前端路由相同。我怀疑这在本地运行时无关紧要,因为指定了不同的端口,但我对 Heroku 如何提供文件以验证是否属实知之甚少。
解决方案
只需将服务和后端路由更新为与应用路由模块路由不同。
就我而言,后端路由已更新为blog/all
,Angular 服务上的 http 调用已更新为匹配。
服务:
//calls the server with a GET method
getBlog(){
console.log("Blog service")
return this.http.get(`/blog/all`, {withCredentials: true});
}
服务器:
router.route('/blog/all').get((req, res) =>{
console.log('Blog route called');
BlogPost.find((err, allPosts) => {
if(err){
console.log('Error' + err);
throw new Error('Unable to load blog posts');
} else {
res.json(allPosts);
}
});
应用路由模块:
{ path: 'blog', component: BlogComponent },
推荐阅读
- express - 护照JS如何处理会话cookie?
- c - 使用 getopt() - 打开、读取和写入文件
- office365 - 在 RDP 上安装团队
- string - 如何将字符串的第二个和第三个字符作为整数 - C89
- r - 具有比例和因子数据的 geom_histogram
- django - Django Bad Reqsut 400 问题
- python-3.x - PyMuPDF 如何删除注释?
- kubernetes - 云平台如何保证服务不宕机
- bash - `inotifywait` 不会在带有 `-e delete_self` 的 bash 脚本中终止;但在交互式外壳中
- django - 如何使用 MySQL 数据库在 Django 中为非洲/卢萨卡设置时区