Ember 通过 link-to 呈现 html,但 json 通过在浏览器中键入 url

Ember renders html via link-to, but json via typing url in browser

这不会在本地开发中发生,但在部署到 Heroku 之后,如果我导航到我的应用程序的根页面,它会加载正常,如果我单击 "posts" link,它会加载我所有的html 中的 post 秒。但是,如果我通过在浏览器的 url 输入中键入 url 导航到同一页面,或者即使我只是单击刷新按钮,它也会加载 json 而不是 html .检查请求,我发现它没有发送查询参数(因此 json 没有分页)并且请求 headers.

中没有 Content-Type

更新

我尝试在 rails 中使用 "api" 命名我的路由,并在 ember 中更新 config/environment.js 中的 apiURL。现在,就像上面一样,如果我单击 links,它可以正常工作,但如果我键入 url 或刷新,则不会,但现在没有加载 json,没有加载任何内容并且出现错误后端是 No route matches [GET] "/posts"。所以我猜 ember 中的 link_to 不会将 "api" 插入 url

命名空间对我来说并不重要,我只是觉得它可能有帮助。但也许它揭示了我对某人的根本问题是什么?

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

// 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

这听起来像是网络服务器(nginx 或您在 heroku 上使用的任何东西)配置的问题 - 它 returns 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 和前端和后端的端口是相同的。

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

Keep in mind that your server must serve the Ember app from all the URLs defined in your Router.map function. In other words, if your user directly navigates to /posts/new, your server must be configured to serve your Ember app in response.

我认为 "server",在我的情况下,指南意味着我的 rails api。无论如何,我最终解决这个问题的方法是发生在 ember-cli-rails gem 和相应的 ember-cli-rails- addon 基本上抽象了这两个框架的大量配置以相互配合,并且作为奖励与 Heroku 集成得很好,便于部署。我本来想在没有魔术插件的情况下解决这个问题,但无论如何。现在可以使用了。

这里非常重要的问题是您如何将应用程序部署到 heroku。 如果您在部署之前捆绑后端(您的 rails API)和前端(您的 ember 应用程序)。

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

由于 ember 执行客户端站点路由,这意味着您的 rails 后端在遇到带有未知 URL 的 HTTP GET 请求时必须为 index.html 提供服务。所以基本上你的 index.html 变成了你的 404 文件,除了 rails 应该总是用 HTTP 200 OK 响应。