【问题标题】:SSI render web component not working using res.send() and #include virtualSSI 渲染 Web 组件无法使用 res.send() 和 #include virtual
【发布时间】:2020-12-30 22:28:02
【问题描述】:

我正在从事一个项目,但我被困在这件事上。我不知道是我遗漏了什么还是失败了

我想以这种方式使用Express 框架呈现自定义元素:

首先我有我以这种方式声明组件的视图文件:

render.js来自一个组件

<my-component><!-- # include virtual="/my-path" --></my-component>

然后,在另一个文件(在另一个组件中)我收到这样的请求:

server.js 来自另一个组件。

app.get('/my-path', (req, res) => {
  res.send(render())
}

其中render() 方法返回一个html,例如&lt;div&gt;hello&lt;/div&gt;

并且my-component 默认不渲染:
my-component.js

class WebComponent extends HTMLElement{

    connectedCallback() {
        console.log('connected component');
    }

}
export default WebComponent;

在这里,我预期的工作流程是:

  1. 加载视图 (render.js)。
  2. my-component 打电话给/my-path 因为&lt;!-- # include virtual="/my-path" --&gt;
  3. 组件被/my-path返回的HTML“填充”。
  4. 查看由服务器渲染到客户端的 Web 组件。

但是它不起作用,组件没有渲染并且是空的。

我已测试访问http://localhost:XXXX/my-path,浏览器正确输出结果。

另外,自定义组件将消息显示到console.log('connected component');,因此组件存在并启动。

但是没有调用路径my-path...为什么?我错过了什么还是我弄错了?也许我需要渲染 Web 组件,但这不是来自服务器的 SSI 渲染?

我还手动触发了服务器中的my-path 路由以检查是否需要调用,但它也不起作用。

编辑: 我将进行编辑以更好地解释:

我以这种方式在服务器端加载 Web 组件(或者我想我会这样做):

  1. 构建并创建page.js 文件
  2. 使用&lt;script src="/my-path/page.js"&gt;&lt;/script&gt;进入布局
  3. server.js 中使用:app.use('/my-path', express.static('./build'));

提前致谢。

【问题讨论】:

  • 渲染你的 web 组件服务器端并不意味着你的组件实际上运行在服务器端。直到它到达客户端并调用customElements.define(),Web 组件才会获得功能。
  • 我构建 Web 组件并使用 &lt;script src="/my-path/page.js"&gt;&lt;/script&gt; 加载到布局中(其中存在 customElements.define 行)。那么组件是在客户端加载而不是在服务器端加载的吗?
  • 否,组件不会被加载到服务器端,因为它是一种客户端技术。但是您可以从您的组件和客户端向/my-path 发出 HTTP 请求,以获取您的组件的数据。

标签: javascript express server-side-rendering ssi


【解决方案1】:

该组件只能在前端工作。如果它想向某个路径发出请求并将该响应用作元素的主体,那么您可以在前端执行此操作。

给你的组件一个path 属性。这应该是从中获取数据的 URL。每当您的组件具有此属性的值时,它都会尝试从该路径获取数据并将其设置为 innerHTML

<my-component path="/my-path"></my-component>

使用observedAttributesattributeChangedCallback 方法将使您能够在第一次渲染时以及每当path 属性的值发生更改时获取新数据。

在您的页面中加载此组件。当它在前端呈现时,它将从path 属性中的值中获取数据并将其设置为innerHTML 值(只要请求成功)。

class MyComponent extends HTMLElement {
  static get observedAttributes() {
    return ['path'];
  }

  constructor() {
    super();
  }

  get path() {    
    return this.getAttribute('path');
  }

  set path(value) {
    this.setAttribute('path', value);
  }

  async fetchPath() {
    if (!this.path) {
      return;
    }

    try {
      const response = await fetch(this.path);
      const html = await response.text();
      this.innerHTML = html;
    } catch (error) {
      console.log(error)
    }
  }

  attributeChangedCallback(attrName, oldValue, newValue) {
    if (attrName === 'path') {
      this.fetchPath();
    }
  }
}

customElements.define('my-component', MyComponent);

【讨论】:

  • 非常感谢!明天我会测试它是否有效。那么,&lt;!-- # include virtual="/my-path" --&gt; 不是必要的/可能的吗?
  • 我不知道它的作用,但在前端该评论只是一个评论。
  • 是一个 SSI 指令:example link.
  • 哇哦,我没听说过。但这清除了一些事情。我的印象是问题出在组件上,但您依赖 SSI 来呈现模板。您是否正在使用使 SSI 与 Node.js 兼容的包?或者您是否考虑过使用 Jade 或 Handlebars 之类的模板引擎来呈现您的 HTML?
猜你喜欢
  • 2017-07-18
  • 2019-04-19
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2017-03-08
  • 1970-01-01
相关资源
最近更新 更多