【问题标题】:How do I get query string value from script path?如何从脚本路径获取查询字符串值?
【发布时间】:2021-06-16 00:38:23
【问题描述】:

我正在将我的 Javsacript 文件添加到脚本路径中具有不同查询字符串的页面中,如下所示:

第1页:

<script type="text/javascript" src="file.js?abc=123"></script>

第2页:

<script type="text/javascript" src="file.js?abc=456"></script>

第3页:

<script type="text/javascript" src="file.js?abc=789"></script>

在我的 Javascript 文件中,如何获取“abc”参数的值?我尝试为此使用 window.location,但这不起作用。

如果有帮助,下面是我用来查找查询字符串参数值的函数:

function getQuerystring(key, defaultValue) {
    if (defaultValue == null) defaultValue = "";
    key = key.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + key + "=([^&#]*)");
    var qs = regex.exec(window.location.href);
    if (qs == null)
        return defaultValue;
    else
        return qs[1];
}

【问题讨论】:

标签: javascript html


【解决方案1】:

这是可能的。见Passing JavaScript arguments via the src attribute。关键是,由于 HTML(not XHTML)中的脚本在加载时执行,这将允许脚本找到自己,因为它在触发时始终是页面中的最后一个脚本–

var scripts = document.getElementsByTagName('script');
var index = scripts.length - 1;
var myScript = scripts[index];
// myScript now contains our script object
var queryString = myScript.src.replace(/^[^\?]+\??/,'');

然后你只需应用查询字符串解析。

【讨论】:

  • "...因为 HTML(不是 XHTML)中的脚本在加载时执行..." 请注意,defer and async 属性会修改该行为,所以如果您重新使用它们,这可能不起作用:您的脚本可能不是该系列中的最后一个。依靠它无论如何都会让我不寒而栗,所以我可能会使用src 上的文件名和过滤器(当然这会引入文件不能重命名的限制)。
  • 如果你用不同的参数多次引用同一个脚本,过滤 src 可能会很棘手。
  • 您可以使用document.currentScript,这是运行实际代码的实际脚本标签。
  • @MichelMattos 是的,currentScript 很酷! ...除非你需要支持 IE :-(
【解决方案2】:

首先,技术上的答案:如果你为你的脚本标签分配一个 ID,你就可以获取它的src,然后解析出查询字符串。

<script id="whatever" type="text/javascript" src="file.js?abc=123"></script>

 

var path = document.getElementById('whatever').src;
// ...

有了这个答案,我想表达我的担忧——这充满了糟糕的设计决策。你为什么以这种方式包含你的脚本(使用查询字符串)?如果您正在尝试优化您的网站(通过一个可以为后续页面缓存的大型脚本),这种方法实际上是适得其反,因为浏览器会在每个页面由于不同的查询字符串。正确的做法是在每个页面上都有一个大的共享文件,然后是一个特定于页面的小文件。

【讨论】:

  • Josh3736 - 一个原因(这也是我通过 Google 搜索来到这里的原因)是为了处理在其他地方使用的小部件。例如,我正在执行
  • 我喜欢这个答案。但是如果使用这样的方法,我可能会做这样的事情:
  • @Tyler,这可能就是我今天的做法。请注意,这个答案是 4 年前写的,在 HTML 5 data 属性被广泛支持之前。
  • 另一个原因可能是版本控制。当您希望在部署新版本时重新加载脚本时。然后你可能想要访问脚本本身的版本号。
  • 我怎么没想到 :D
【解决方案3】:

由于 Internet Explorer 的使用已不再重要。您可以使用document.currentScriptnew URL,它们会返回一个带有相关标签&lt;script&gt; 的字符串。

const search            = new URL(document.currentScript.src).search.substring(1)
const stringPreparation = decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"')
const qs                = JSON.parse('{"' + stringPreparation + '"}')

你可以把这段代码减少到一行,但不推荐,让minifier脚本来做。

【讨论】:

    【解决方案4】:

    您可以使用URL apidocument.currentScript 来检索这个`

    const url = new URL(document.currentScript.getAttribute('src'));
    const scriptParams = Object.fromEntries(url.searchParams)
    console.log(scriptParams);
    

    【讨论】:

      【解决方案5】:

      我有一个快速简单的解决方案,可以使用 jQuery 从 js 文件中提取查询字符串来获取脚本标记源属性,并且只需使用两个单独的函数来解析 JS 文件路径和查询字符串。显然,jQuery 是必需的。

      $(document).ready(function() {
      
          var p = parseURL($('script[src*="thisfile.js"]').attr('src'));
      
          console.log(p);
      
      });
      
      // Parse a URL into its parts
      function parseURL(url)
      {
          var p = document.createElement('a');
      
          p.href = url;
      
          var obj = {
              'protocol' : p.protocol,
              'hostname' : p.hostname,
              'port' : p.port,
              'pathname' : p.pathname,
              'search' : p.search,
              'query' : p.search.substring(1),
              'args' : parseStr(p.search.substring(1)),
              'hash' : p.hash,
              'host' : p.host
          };
      
          return obj;
      }
      
      // Parse a query string
      function parseStr(string)
      {
          var args = string.split('&');
          var argsParsed = {};
      
          for (i = 0; i < args.length; i++)
          {
              var arg = decodeURIComponent(args[i]);
      
              if (arg.indexOf('=') == -1)
              {
                  argsParsed[arg.trim()] = true;
              }
              else
              {
                  var kvp = arg.split('=');
                  argsParsed[kvp[0].trim()] = kvp[1].trim();
              }
          }
      
          return argsParsed;
      }
      

      【讨论】:

      • 你确定这是最简单的方法吗?而且你需要另外硬编码文件名。
      • Ashley 上面的回答可能比我的简单。我的 sn-p 只是我发布此内容时准备好的一个。而且您不需要对文件进行硬编码。您只需要在第 3 行定制 jQuery 选择器以满足您的特定需求。在这种情况下,我需要的是上面原始帖子中要求的特定文件。
      猜你喜欢
      • 2013-04-28
      • 1970-01-01
      • 2013-07-07
      • 1970-01-01
      • 1970-01-01
      • 2019-12-13
      • 2020-05-16
      • 1970-01-01
      相关资源
      最近更新 更多