zoukankan      html  css  js  c++  java
  • # Failed to execute 'write' on 'Document' It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

    为了不在页面初始化的时候,同时加载多个类似功能api,想通过Promise 实现动态加载。基本逻辑如下:

    let getBaiduGeo = new Promise((resolve, reject) => {
            let baiduGeo_url =
              "http://api.map.baidu.com/api?v=3.0&ak=GgdUzLNYFlZKrdDPzei6gxc0DMCxTNdy";
            let baiduGeo_api_dom = document.createElement("script");
            baiduGeo_api_dom.charset = "utf-8";
            baiduGeo_api_dom.src = baiduGeo_url;
            baiduGeo_api_dom.id = "baiduGeoid";
            document.head.appendChild(baiduGeo_api_dom);
    
            if (document.getElementById("baiduGeoid")) {
              resolve();
            } else {
              reject(err);
            }
          });
          getBaiduGeo
            .then(() => {
              var geolocation = new BMap.Geolocation();
              geolocation.getCurrentPosition(function (r) {
                if (r) {
                  console.log(
                    `<-----getLocationPoweredByBaiduGeoJS
                ${JSON.stringify(result)}
                getLocationPoweredByBaiduGeoJS----->`
                  );
                } else {
                  getQingJsAPI();
                }
              });
            })
            .catch((err) => {
              console.log(err);
            });
    
          let getQingJsAPI = function () {
            let getQingJs = new Promise((resolve, reject) => {
              let qingjs_url =
                "https://static.yunzhijia.com/public/js/qing/latest/qing.js";
              let qingjs_api_dom = document.createElement("script");
              qingjs_api_dom.charset = "utf-8";
              qingjs_api_dom.src = qingjs_url;
              qingjs_api_dom.id = "qingjsid";
              document.head.appendChild(qingjs_api_dom);
              if (document.getElementById("qingjsid")) {
                resolve();
              } else {
                reject(err);
              }
            });
            getQingJs.then(() => {
              qing.call("getLocation", {
                success: function (result) {
                  console.log(
                    `<-----getLocationPoweredByQingJS
                ${JSON.stringify(result)}
                getLocationPoweredByQingJS----->`
                  );
                },
              });
            });
          };
    

    运行时,遇到了浏览器报错:

    Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

    大意,写入失败。不能通过异步加载的方式加载额外的脚本,除非显示的被打开?

    不太懂:

    网上查:

    An asynchronously loaded script is likely going to run AFTER the document has been fully parsed and closed. Thus, you can't use document.write() from such a script (well technically you can, but it won't do what you want).

    You will need to replace any document.write() statements in that script with explicit DOM manipulations by creating the DOM elements and then inserting them into a particular parent with .appendChild() or .insertBefore() or setting .innerHTML or some mechanism for direct DOM manipulation like that.

    https://stackoverflow.com/a/24297863

    大意:文档流加载完毕,无法再通过write插入脚本。

    但是可以通过appendChild()或者insertBefore()或者innerHTML 写入。

    但是我并没有通过write()方法写入啊

    单独测试:

    qingjs:

            let getQingJs = new Promise((resolve, reject) => {
              let qingjs_url =
                "https://static.yunzhijia.com/public/js/qing/latest/qing.js";
              let qingjs_api_dom = document.createElement("script");
              qingjs_api_dom.charset = "utf-8";
              qingjs_api_dom.src = qingjs_url;
              qingjs_api_dom.id = "qingjsid";
              document.head.appendChild(qingjs_api_dom);
              if (document.getElementById("qingjsid")) {
                resolve();
              } else {
                reject(err);
              }
            });
            getQingJs.then(() => {
              qing.call("getLocation", {
                success: function (result) {
                  console.log(
                    `<-----getLocationPoweredByQingJS
                ${JSON.stringify(result)}
                getLocationPoweredByQingJS----->`
                  );
                },
              });
            });
    

    没问题,可以正常加载内容:

    <-----getLocationPoweredByQingJS
    {"success":"true","errorCode":"","data":{"address":"浙江省台州市黄岩区东城街道永高股份(东南门)永高股份有限公司(双浦厂区)","city":"台州市","longitude":121.29986843532986,"district":"黄岩区","addressdetail":"浙江省台州市黄岩区东城街道永高股份(东南门)永高股份有限公司(双浦厂区)","latitude":28.663372667100695,"accuracy":65,"name":"永高股份(东南门)永高股份有限公司(双浦厂区)","province":"浙江省"},"error":""}
    getLocationPoweredByQingJS----->

    百度api单独测试:

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Hello, World</title>
        <style type="text/css">
            html {
                height: 100%
            }
            
            body {
                height: 100%;
                margin: 0px;
                padding: 0px
            }
            
            #container {
                height: 100%
            }
        </style>
        <script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=GgdUzLNYFlZKrdDPzei6gxc0DMCxTNdy">
            //v3.0版本的引用方式:src="http://api.map.baidu.com/api?v=3.0&ak=您的密钥"
        </script>
    </head>
    
    <body>
        <div id="container"></div>
        <script type="text/javascript">
            // var map = new BMap.Map("container");
    
            // var point = new BMap.Point(116.331398, 39.897445);
            // map.centerAndZoom(point, 12);
    
            var geolocation = new BMap.Geolocation();
            geolocation.getCurrentPosition(function(r) {
                console.log(r);
                alert('您的位置:' + r.point.lng + ',' + r.point.lat);
    
                return;
                if (this.getStatus() == BMAP_STATUS_SUCCESS) {
                    var mk = new BMap.Marker(r.point);
                    map.addOverlay(mk);
                    map.panTo(r.point);
                    alert('您的位置:' + r.point.lng + ',' + r.point.lat);
                } else {
                    alert('failed' + this.getStatus());
                }
            });
        </script>
    </body>
    
    </html>
    

    依旧报同样错误:

    定位到代码位置:

    原来是BaiduAPI 中写有write,所以才会报错,与我无瓜,百度的这个api不能这样动态加载。

  • 相关阅读:
    Microsoft To-Do无法同步问题 ke xue上网导致
    学习希尔排序
    查找docker无法启动的原因
    挂载只读分区为可读写
    批量重建索引脚本
    frp nginx 80 端口共用
    vue部署nginx 404
    阿里云服务器,数据库热备、暖备、冷备实战-镜像篇(域环境下配置)
    码农老婆的网店
    Wcf调用方式
  • 原文地址:https://www.cnblogs.com/jaycethanks/p/13952218.html
Copyright © 2011-2022 走看看