首页 > 解决方案 > 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>↵&lt;html lang="en">↵&lt;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 查询服务器并将每个帖子发送到前端,这导致了配对错误。

我添加了一个静态登录页面,然后链接到一个新创建的博客/所有路由,该路由查询并发送所有帖子,并且数据传递时没有错误。

有人知道这是为什么吗?

标签: node.jsangularexpressherokuobservable

解决方案


好的,所以我能够想出一个相对简单的解决方案,但是我不能确切地说为什么我发布的代码在本地工作而不是在 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 },

推荐阅读