前端微服务化研究(六):沙盒实现

   日期:2020-08-23     浏览:89    评论:0    
核心提示:在写这个之前,我们先说下fetchfetch什么是fetch: 在msdn上是这样说的,提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。这种功能以前是使用 XMLHttpRequest 实现的。Fetch 提供了一个更理想的替代方案,可以很容易地被其他技术使用,例如 Service Workers。Fetch 还提供了专门的逻辑空间来定义其他与

在写这个之前,我们先说下fetch

fetch

什么是fetch: 在msdn上是这样说的,提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。

这种功能以前是使用 XMLHttpRequest 实现的。Fetch 提供了一个更理想的替代方案,可以很容易地被其他技术使用,例如 Service Workers。Fetch 还提供了专门的逻辑空间来定义其他与 HTTP 相关的概念,例如 CORS 和 HTTP 的扩展。

fetch 与 jQuery.ajax()

当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject, 即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。

fetch() 可以不会接受跨域 cookies;你也可以不能使用 fetch() 建立起跨域会话。其他网站的 Set-Cookie 头部字段将会被无视。

fetch 不会发送 cookies。除非你使用了credentials 的初始化选项。(自 2017 年 8 月 25 日以后,默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改)

fetch简单使用

fetch('http://127.0.0.1:5500/demo1.html')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

在这里我为什么说fetch呢?因为接下要使用这个。因为我们都知道,微前端的出现就是为了解决各个项目之间的联系,也就是把各个项目合并到一个项目中,减少开发的时间。所以每个项目都有相应的地址或者入口,比我们公司都是vue的当页面应用,所以整合起来非常简单,我们通过fetch 请求入口地址拿到html,经过处理插入一个项目中就可以实现。如下:
我的一个项目地址是: http://192.168.1.140:7001/

fetch('http://192.168.1.140:7001/')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });



然后通过解析dom,分别请求js和style
scripts

  const scripts = dom.querySelectorAll('script');
  const paromiseArr =
    scripts &&
    Array.from(scripts).map((item) => {
      if (item.src) {
        const url = window.location.protocol + '//' + window.location.host;
        const path = item.src.replace(url, '');
        const needEntryPath = !/(http|https):\/\/([\w.]+\/?)\S*/.test(path);
        return fetch(`${needEntryPath ? entryPath : ''}${item.src}`.replace(url, '')).then(
          function (response) {
            return response.text();
          }
        );
      } else {
        return Promise.resolve(item.textContent);
      }
    });
  const res = await Promise.all(paromiseArr);
  if (res && res.length > 0) {
    res.forEach((item) => {
      const script = document.createElement('script');
      script.innerText = item;
      subapp.appendChild(script);
    });
  }

style

  const arr = [];
  const styles = dom.querySelectorAll('style');
  const links = Array.from(dom.querySelectorAll('link')).filter(
    (item) => item.rel === 'stylesheet'
  );
  const realArr = arr.concat(styles,links)
  const paromiseArr =
    arr &&
    Array.from(realArr).map((item) => {
      if (item.rel) {
        const url = window.location.protocol + '//' + window.location.host;
        const path = item.href.replace(url, '');
        const needEntryPath = !/(http|https):\/\/([\w.]+\/?)\S*/.test(path);
        return fetch(`${needEntryPath ? entryPath : ''}${item.href}`.replace(url, '')).then(
          function (response) {
            return response.text();
          }
        );
      } else {
        return Promise.resolve(item.textContent);
      }
    });
  const res = await Promise.all(paromiseArr);
  if (res && res.length > 0) {
    res.forEach((item) => {
      const style = document.createElement('style');
      style.innerHTML = item;
      subapp.appendChild(style);
    });
  }

完整的

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>demo</title>
</head>
<body>
  <div>
    <!-- <custom-element>sadasdasdasdas</custom-element> -->
    <div id="main-content"></div>
  </div>
  <script> fetch('http://192.168.1.140:7001/').then(function(response) { return response.text() }).then(async function (text) { const mainApp = document.querySelector('#main-content'); let tempNode = document.createElement('div') tempNode.innerHTML = text mainApp.appendChild(tempNode) return { tempNode, mainApp } }).then(async function ({ tempNode, mainApp}) { await loadScripts() await loadStyle() }) async function loadScripts (dom, mainApp) { const scripts = tempNode.querySelectorAll('script'); const paromiseArr = scripts && Array.from(scripts).map((item) => { if (item.src) { const url = window.location.protocol + '//' + window.location.host; const path = item.src.replace(url, ''); const needEntryPath = !/(http|https):\/\/([\w.]+\/?)\S*/.test(path); return fetch(`${needEntryPath ? entryPath : ''}${item.src}`.replace(url, '')).then( function (response) { return response.text(); } ); } else { return Promise.resolve(item.textContent); } }); const res = await Promise.all(paromiseArr); if (res && res.length > 0) { res.forEach((item) => { const script = document.createElement('script') script.innerText = item mainApp.appendChild(script) }) } } async function loadStyle (dom, mainApp) { const scripts = dom.querySelectorAll('script'); const paromiseArr = scripts && Array.from(scripts).map((item) => { if (item.src) { const url = window.location.protocol + '//' + window.location.host; const path = item.src.replace(url, ''); const needEntryPath = !/(http|https):\/\/([\w.]+\/?)\S*/.test(path); return fetch(`${needEntryPath ? entryPath : ''}${item.src}`.replace(url, '')).then( function (response) { return response.text(); } ); } else { return Promise.resolve(item.textContent); } }); const res = await Promise.all(paromiseArr); if (res && res.length > 0) { res.forEach((item) => { const script = document.createElement('script'); script.innerText = item; mainApp.appendChild(script); }); } } </script>
</body>
</html>

初步思路是这样的实现的的原理;
更完整的请看这篇的实现

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服