【问题标题】:Ember renders html via link-to, but json via typing url in browserEmber 通过链接呈现 html,但通过在浏览器中输入 url 呈现 json
【发布时间】:2019-02-17 21:09:19
【问题描述】:

这不会在本地开发中发生,但是在部署到 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 没有在 url 中插入“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

【问题讨论】:

  • 你在使用任何 Heroku buildpacks 吗?
  • 您能否详细说明您如何为您的 ember 资产提供服务
  • 我只是将它们放在 Rails 应用程序的公共文件夹中。如果您要问的话,他们不在 CDN 上。要回答@mwp,我没有使用 Heroku Buildpack。只是自动选择的红宝石。

标签: ember.js


【解决方案1】:

这听起来像是网络服务器(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 和端口是相同的。

【讨论】:

  • 我不知道如何在 Heroku 上编辑 Web 服务器的配置。我用我的一些代码更新了我的问题,因为它不是网络服务器问题而是余烬问题。
【解决方案2】:

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

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

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

【讨论】:

  • 嘿@Lux,我正在将用于生产的 Ember 应用程序构建到 Rail 应用程序的公共文件夹中。根据一些互联网研究,我想我现在“每当遇到带有未知 URL 的 HTTP GET 请求时就为 index.html 提供服务”,就像你说的那样,但它仍然无法正常工作。链接仍然有效(像以前一样),但是现在当我重新加载或直接导航到一个 url 时,页面是空白的,它会在浏览器的控制台中抛出 UnrecognizedURLError: /index.html。所以我用我的路线文件更新了我的问题。你能看一下吗,如果我们能做到这一点,我很乐意将你的答案标记为正确!
  • 你有没有考虑加入 ember 社区 discord 服务器并在#help 频道寻求帮助?
  • 我从未听说过。可以给我链接吗?
【解决方案3】:

好吧,我从来没有真正想出解决这个问题的普通方法。我确实认为问题出在 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 很好地集成,以便于部署。我本来想在没有魔法插件的情况下解决这个问题,但无论如何。现在可以使用了。

【讨论】:

  • In this answer 有人建议将 FE 和 API 部署为两个独立的 Heroku 应用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
相关资源
最近更新 更多