【问题标题】:Polymer Routing聚合物路由
【发布时间】:2016-06-01 20:09:29
【问题描述】:

我对 Polymer 非常陌生,但正在使用 Polymer 模板进行测试:

https://www.polymer-project.org/1.0/start/toolbox/set-up

一切正常,除非我输入直接网址,例如 site.com/page

app-route: https://github.com/PolymerElements/app-route 如果我单击带有 /page 的 href 链接将正确加载内容,但如果我直接输入 url 将无法正确加载(我收到 404 错误)。

我错过了什么?我没有更改演示应用程序中的任何代码(当我直接输入 url 时,演示应用程序对我不起作用)。

【问题讨论】:

  • 在 OSX El Capitan、Chrome 51 中运行良好。您的测试环境是什么?你到底输入了什么?
  • 我在 Chrome 版本 50.0.2661.102(64 位)上的 OSX El Capitan 10.11.5 上使用 MAMP 这很奇怪,因为我在 MAMP 上的 polymer/ 上设置了一个站点,当我单击它时它可以工作一个 href 但当我输入 polymer/somelink 时它是 404。
  • 您可能需要向服务器添加逻辑,以便为应用程序中的其他子路由提供 index.html。我猜你的服务器就像“嘿狗,这里没有名为 /some/subpath 的 HTML 文件!”
  • 你在用“hashbang”做什么?你需要将它包含在浏览器的位置吗?见stackoverflow.com/questions/30925003/…
  • 你解决了这个问题吗?我也有同样的问题,互联网上没有关于它的内容。

标签: polymer polymer-1.0


【解决方案1】:

您需要在 index.html 所在的位置添加一个 .htaccess 文件。 这是其中的路由和铁页的完整工作代码。

.htaccess

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">

    <title>....</title>
    <meta name="description" content="....">

    <link rel="manifest" href="/manifest.json">
    <link rel="import" href="/src/main-app.html" async>

    <style>

      .....
    </style>

  </head>
  <body>
    <main-app></main-app>
    <script>
      window.performance && performance.mark && performance.mark('index.html');

      Polymer = {lazyRegister: true, dom: 'shadow'};

      (function() {
        if ('registerElement' in document
            && 'import' in document.createElement('link')
            && 'content' in document.createElement('template')) {
          // platform is good!
        } else {
          // polyfill the platform!
          var e = document.createElement('script');
          e.src = '/bower_components/webcomponentsjs/webcomponents.min.js';
          document.body.appendChild(e);
        }
      })();
    </script>
  </body>
</html>

ma​​in-app.html

 <!-- START OF IMPORTS -->
    <link rel="import" href="../bower_components/polymer/polymer.html">
    <!-- Iron Ajax -->
    <link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">
    <!-- Route -->
    <link rel="import" href="../bower_components/app-route/app-location.html">
    <link rel="import" href="../bower_components/app-route/app-route.html">
    <!-- Iron Pages-->
    <link rel="import" href="../bower_components/iron-pages/iron-pages.html">







    <!-- Fragments -->
    <link rel="import" href="you-page-to-go-to.html">



    <dom-module id="main-app">
      <template>
      <style>
     ....
      </style>

      <!-- App Routing -->
      <app-location route="{{route}}"></app-location>
      <app-route
      route="{{route}}"
      pattern="/:page"
      data="{{routeData}}"
      tail="{{subroute}}">
      </app-route>


  <iron-pages role="main" selected="[[page]]" attr-for-selected="name" selected-attribute="visible">
                <!-- General -->
                <you-page-to-go-to name="you-page-to-go-to"></you-page-to-go-to>
              </iron-pages>

    </template>

    <script>
    Polymer({
      is: 'main-app'
      properties: {
        page: {
          type: String,
          reflectToAttribute: true,
          observer: '_pageChanged'
        },
        title:{
          type:String,
          value:"null"
        }
      },
      /* For route */
      observers: [
        '_routePageChanged(routeData.page)'
      ],
      _routePageChanged: function(page) {
        this.page = page || 'home';
        this.drawerOpened = false;
      },
      _pageChanged: function(page, oldPage) {
        if (page != null) {

          this.title = page;

          this.importHref(
            this.resolveUrl('main-' + page + '.html'),
            function() {
              this._pageLoaded(Boolean(oldPage));
            }, null, true);
          }
        },
        _pageLoaded: function(shouldResetLayout) {
          if (shouldResetLayout) {
            this.async(function() {
            }, 1);
          }
        },

      });
      </script>
    </dom-module>

【讨论】:

    【解决方案2】:

    我也有这个问题。经过数小时的搜索,我没有找到任何解决方案。我必须找到自己的解决方案,最终我成功了。你有两个选择:

    1. 在应用位置上使用 use-hash-as-path 属性(对 SEO 不友好)
    2. 调整您的 Web 服务器配置并将所有 404 请求重定向到主页

    我正在使用选项 2,我的 Web 服务器是 IIS。

    【讨论】:

      【解决方案3】:

      您需要让后端将所有请求(无论请求的 URL/路径)路由到同一页面(可能是 index.html 吗?)

      Polymer 的应用路由器将处理其余的...

      说明:当您在浏览器中键入 URL 时,会发生这种情况:

      • 浏览器尝试将路由与 HTML 文件匹配
      • 如果找不到,您会收到 404

      你真正想要的是 app-router 来处理这个问题,但是当你的 HTML 没有加载时怎么会发生呢!

      因此,根据您的服务器堆栈,您希望拥有所有 /app/* 类型的路由来加载 index.html 文件。这样做会将/app/home/app/settings/app/foo/bar 等页面全部发送到index.html。然后app-router 读取window.location 变量以将URL 与其路由模式之一匹配,然后运行适当的回调。

      这有意义吗?


      前端区别:(关于区别的技术说明)

      当您正常与您的应用交互并且URL 发生更改时,不会向服务器发出任何网络请求。事实上,浏览器在这里所​​做的是它使用 browser push-states 修改浏览器的历史堆栈。这允许前端修改urlbrowser history 以保持状态,而无需每次都重新加载整个页面。

      【讨论】:

        【解决方案4】:

        这是您的服务器配置的问题。当你第一次加载 up 时,你的服务器知道它需要服务 index.html 文件,因为所有的网络服务器都默认使用这个文件。

        然后,当您单击链接时,它不会向服务器询问该 url...它正在运行 javascript 来更改 dom。 javascript 是进行重写的实体,它请求一个原始 html 文件,您的服务器知道如何找到该文件。

        现在,当您尝试直接访问某个 url 时,您的服务器会查找该“文件”但找不到它,因此您会得到 404。

        要解决此问题,您需要在服务器配置中创建适当的重写规则。大多数时候,你会做类似的事情

        try_file $uri index.html;

        在 Nginx 中。这会告诉你的服务器,嘿,如果你在那个地址没有找到东西,不要 404... 让我们去 index.html 并让 javascript 处理它。

        【讨论】:

          猜你喜欢
          • 2015-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多