Ember通过链接呈现html,但通过在浏览器中键入url呈现json

时间:2019-02-17 21:09:20

标签: ember.js

这不是在开发中本地发生的,但是在部署到Heroku之后,如果我导航到应用程序的根页面,它将很好地加载,如果我单击“发布”链接,它将以html加载我的所有发布。但是,如果我通过在浏览器的url输入中键入url导航到同一页面,或者即使我只是单击“刷新”按钮,它也会加载json而不是html。检查请求,我发现它没有发送查询参数(因此json没有分页),并且请求标头中没有Content-Type。

更新

我尝试用“ api”在Rails中命名路由,并在ember中的config / environment.js中更新apiURL。现在,就像上面一样,如果单击链接,它可以正常工作,但是如果我键入URL或刷新,则不能正常工作,但是现在不用加载json,什么也没有加载,并且后端的错误是No route matches [GET] "/posts"。所以我想ember中的link_to不会在网址中插入“ api”

名称空间对我来说并不重要,我只是认为这可能会有所帮助。但这也许揭示了我对某人的潜在问题?

此外,我发现了这个EMBER direct route URL access dont load data,似乎与我的问题非常相似,因此我将发布一些相关代码:

// routes/posts.js
import Route from '@ember/routing/route';

export default Route.extend({
  queryParams: {
    page: {
      refreshModel: true
    },
    limit: {
      refreshModel: true
    }
  },

  model(params) {
    return this.store.query('post', {
      filter: {
        name: "categories.name",
        op: "!=",
        val: "Projects"
      },
      limit: params.limit,
      page: params.page,
      includes: [
        "tags",
        "categories"
      ]
    });
  }
});
// routes/post.js
import Route from '@ember/routing/route';

export default Route.extend({
  model(params) {
    return this.store.findRecord('post', params.post_id);
  }
});

更新2

这是我的Rails路线文件

# config/routes.rb
Rails.application.routes.draw do
  namespace :api do
    resources :categories
    resources :comments
    resources :posts
  end

  get "*path", :to => redirect("index.html")
end

3 个答案:

答案 0 :(得分:2)

这听起来像是网络服务器(nginx或您在heroku上使用的任何工具)配置的问题-它返回API响应,而不是提供前端应用程序。

我可以举例说明ember应用程序的正确nginx配置:

server {
    listen 80;
    server_name jira-stats.domain;
    return 301 https://$host$request_uri;
}

server {
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/jira-stats.domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/jira-stats.domain/privkey.pem;
        server_name jira-stats.domain;
        root /path/to/dist;

        location ~ /.well-known {
                allow all;
        }

        # Deny all . files
        location ~ /\. {
                deny all;
        }

        index index.html
        access_log off;
        gzip on;
        gzip_comp_level 9;
        gzip_types text/plain text/xml text/css application/x-javascript image/png image/gif image/jpeg image/jpg;

        location / {
                include /etc/nginx/mime.types;
                try_files $uri /index.html;
        }
}

在此配置location中,这一部分非常重要。如果请求的路径不是文件,它将指示nginx服务index.html。然后,Ember的路由器将解析url并呈现正确的路由。

您还需要将API移到与80/443不同的子域或端口。从您的问题来看,我认为前端和后端的URL和端口是相同的。

答案 1 :(得分:1)

嗯,我从来没有真正想出解决此问题的有效方法。我确实认为问题出在Rails(特别是路由器)而不是服务器,但是我可能错了。使我相信这是Ember指南https://guides.emberjs.com/release/configuring-ember/specifying-url-type/#toc_history中的这一点,具体是:

  

请记住,您的服务器必须通过Router.map函数中定义的所有URL为Ember应用程序提供服务。换句话说,如果您的用户直接导航到/ posts / new,则必须将您的服务器配置为提供Ember应用作为响应。

在我看来,该指南的意思是“服务器”,即我的Rails API。无论如何,我最终解决此问题的方法是通过在ember-cli-rails gem和相应的ember-cli-rails-addon上进行,它们基本上抽象出了这两个框架的许多配置,以便彼此协同工作,并且作为奖励,它与Heroku集成良好,易于部署。我本来想在没有魔术插件的情况下解决此问题,但无论如何。现在可以使用了。

答案 2 :(得分:1)

这里非常重要的问题是如何将应用程序部署到heroku。 如果在部署与否之前将后端(您的Rails API)和前端(您的em​​ber应用程序)捆绑在一起。

如果将它们捆绑在一起,则rails后端不仅负责提供API,还负责提供ember应用程序。这意味着所有余烬文件(jscss)将由rails作为静态资产提供。

由于ember会进行客户端站点路由,因此这意味着您的rails后端必须在处理包含未知URL的HTTP GET请求时为index.html提供服务。因此,基本上,您的index.html变成了您的404文件,只是rails应该始终以HTTP 200 OK响应。