A cosa serve un tag <script> all'interno di un tag <noscript>?


139

Ultimamente sono stato su una "fonte di visualizzazione" su siti Web con design e contenuti interessanti. Uno di quei siti Web, Squarespace , contiene blocchi di <script>tag all'interno di un <noscript>tag, in questo modo:

<!-- Page is at: http://squarespace.com -->
...
...
<noscript id="inline-deps">
  <link rel="stylesheet" type="text/css" href="//cloud.typography.com/7811972/758964/css/fonts.css" />

  <script type="text/javascript" src="https://static.squarespace.com/static/ta/5134cbefe4b0c6fb04df8065/7400/assets/logomark/logomark.min.js?37"></script>
  <link rel="stylesheet" href="https://static.squarespace.com/static/ta/5134cbefe4b0c6fb04df8065/7400/assets/logomark/logomark.min.css?37" type="text/css" />
</noscript>
...
...

Mi è sembrato strano e mi ha fatto cercare su Google informazioni per vedere se c'è una sorta di funzionalità / scopo nascosti per un così strano codice HTML, ma senza risultati. C'è qualche tipo di scopo nell'avere <script>tag all'interno degli <noscript>elementi, o è solo un esempio di HTML non valido?


18
IMHO non ha senso ed è solo un errore.
Sebastien C.,

12
Forse è solo un modo strano di commentare JS.
AlexR,

8
A giudicare dal fatto che essi hanno un colpo di testa completo (compresi <base href="">, <meta … />, <title>e <link … />gli elementi) sembra che stanno abusando <noscript>per template.
Bergi,

2
Ottima domanda! Ma orribile perché ora hai dato il via a un'altra follia di "view source" per me .. Sono appena uscito da quell'abitudine!
Bobo,

2
@ Bobo: Ma guardare il codice per capire cosa succede all'interno di Matrix è una buona cosa! ;)
Agent.Logic_

Risposte:


139

Ho fatto qualche ricerca nel loro codice e ho trovato questo frammento (l'ho ripulito per renderlo più leggibile):

var DepLoader = (function () {
  function init() {
    var dependencies = document.getElementById("inline-deps");
    if (!dependencies || JS.hasClass(document.body, "deps--loaded")) {
      webfontsReady();
    } else {
      var html = dependencies.innerText || dependencies.textContent;
      JS.addClass(document.body, "deps--loaded");
      processRaw(html);
    }
  }

  function isListed(a, b) {
    for (var i = 0; i < b.length; i++) {
      if (a.indexOf(b[i]) !== -1) {
        return true;
      }
    }
    return false;
  }

  function webfontsReady() {
    JS.fireCustom("webfontsReady");
  }

  function processRaw(html) {
    var el = document.createElement("div");
    el.innerHTML = html;

    var scripts = el.querySelectorAll("script");
    var styles = el.querySelectorAll("link");
    var common, signup, dialog, systemPage, commerce;
    var others = [];
    var inline = [];
    var styleWhiteList = ["site.css", "dialog-", "signup-", "logomark"];
    var scriptBlackList = ["management-", "ckeditor-"];

    for (var i = 0; i < styles.length; i++) {
      var style = styles[i];
      if (style.href.indexOf("fonts.css") !== -1) load(style, webfontsReady);
      if (isListed(style.href, styleWhiteList)) load(style);
    }

    for (var i = 0; i < scripts.length; i++) {
      var script = scripts[i];
      var src = script.src;

      if (!src && script.getAttribute("data-sqs-type") !== "dynamic-assets-loader" && script.innerHTML.indexOf("SQUARESPACE_ROLLUPS") === -1) {
        eval(script.innerHTML);
      }
    }

    if (window.SQUARESPACE_ROLLUPS) {
      for (var key in SQUARESPACE_ROLLUPS) {
        var rollup = SQUARESPACE_ROLLUPS[key];
        var js = rollup.js;
        var css = rollup.css;

        if (key.indexOf("common") !== -1) {
          common = js;
        } else if (key.indexOf("commerce") !== -1) {
          commerce = js;
        } else if (key.indexOf("signup") !== -1) {
          signup = js;
        } else if (key.indexOf("dialog") !== -1) {
          dialog = js;
        } else if (key.indexOf("system-page") !== -1) {
          systemPage = js;
        } else if (key) {
          others = others.concat(js);
        } else {
          inline = inline.concat(js);
        }
      }
    }

    for (var i = 0; i < scripts.length; s++) {
      var script = scripts[i];
      var src = script.src;

      if (!isListed(src, scriptBlackList)) {
        if (src.indexOf("common-") !== -1) {
          common = script;
        } else if (src.indexOf("commerce-") !== -1) {
          commerce = script;
        } else if (src.indexOf("signup-") !== -1) {
          signup = script;
        } else if (src.indexOf("dialog-") !== -1) {
          dialog = script;
        } else if (src.indexOf("system-page-") !== -1) {
          systemPage = script;
        } else if (src) {
          others.push(script);
        } else {
          inline.push(script);
        }
      }
    }

    function loadOthers() {
      for (var i = 0; i < inline.length; i++) {
        if (inline[i].getAttribute("data-sqs-type") !== "dynamic-assets-loader") {
          load(inline[a]);
        }
      }

      for (var i = 0; i < others.length; i++) {
          load(others[i]);
      }

      JS.fireCustom("dependenciesLoaded");
    }

    var loadSystemPage = load.bind(this, systemPage, loadOthers, "system page");
    var loadSignup = load.bind(this, signup, loadSystemPage, "signup");
    var loadCommerce = load.bind(this, commerce, loadSignup, "commerce");
    var loadDialog = load.bind(this, dialog, loadCommerce, "dialog");
    var loadCommon = load.bind(this, common, loadDialog, "common");

    loadCommon();
  }

  function load(tag, callback, label) {
    var head = document.head;

    if (Array.isArray(tag)) tag = { nodeName: "SCRIPT", src: tag[0] };

    if (!tag) {
      if (callback) callback();
      return;
    }

    if (tag && (tag.src || tag.href)) {
      var child;
      if ("SCRIPT" === tag.nodeName) {
        child = document.createElement("script");
        child.src = tag.src;

        if (child.src.indexOf("combo") !== -1) {
          callback = function () {
            Y.Squarespace.FrontSite.Core.domReady(true)
          };
        }
      } else {
        if ("LINK" === tag.nodeName && "stylesheet" === tag.rel) {
          child = document.createElement("link");
          child.href = tag.href;
          child.rel = "stylesheet";
          child.tyle = "text/css";
        }

        if (child) {
          child.onload = callback;
          head.appendChild(child);
        }
      }
    } else {
      try {
        eval(tag.innerHTML);
      } catch (e) {}
    }
  }

  return { init: init, webfontsReady: webfontsReady };
})();

Come puoi vedere, il <noscript>tag ha l'ID #inline-deps, a cui fa riferimento il codice (riga 3) per caricare le dipendenze in modo asincrono e su richiesta.

Probabilmente usano un <noscript>elemento in quanto consente loro di accedere direttamente agli elementi DOM, invece di doverlo inserire in una stringa o in un commento (che ritengo particolarmente negativo, poiché i commenti non sono pensati per informazioni effettive) e quindi analizzarli. Impedisce inoltre l'esecuzione di script e stili CSS fino a quando non viene caricato specificatamente.

Personalmente trovo questo un abuso di <noscript> tag. Non sono nemmeno sicuro che sia un codice HTML5 valido. L'uso di altri metodi come la dichiarazione di dipendenze in un oggetto JavaScript con un caricatore di script dovrebbe essere usato ove possibile.


71
Quei subdoli hacker di codice;). Spero che lo abbiano documentato bene, prima che qualche ragazzo intelligente lo cancellasse "dal momento che non serve a niente".
Patrick Hofman,

6
Ho visto <script type="text/html">...</script>usato per lo stesso scopo: qualcuno ha i pro / contro dei due?
Shai,

4
È probabile che qualsiasi cosa all'interno <noscript>sia visibile agli utenti non JavaScript; la maggior parte dei siti semplicemente non supporta quegli utenti, ma vorresti anche mostrare loro un semplice messaggio esplicativo.
Katana314,

8
Queste sono alcune pratiche straordinariamente cattive che stanno eseguendo
dal

3
Qualcuno può spiegare cosa fa questo codice? .. 86 voti positivi e non ho idea di cosa sia questo codice .. Mi sento stupido! ..
Lakshay
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.