在IE浏览器中,new URL(location.href)无法正常工作。

31
我在IE中遇到了使用 new URL('address') 方法的问题。
我有以下代码:

请直接提供需要翻译的内容。

var href =  location.href;
var hrefParams = new URL(href);
var api = hrefParams.searchParams.get("api");

在Firefox和Chrome中,它可以正常工作,并且我将获得属性"api"的值。

但是在IE中,我会在控制台上收到错误:

SCRIPT445:对象不支持此操作

控制台错误调试器指向问题所在行:

var hrefParams = new URL(href);
为了解决另一个问题,我已经调用了脚本。
<script type="text/javascript" src="js/bluebird.min.js"></script>

但这并不能解决这个问题。

有什么办法可以在IE中修复它吗?


IE不支持URL API。Bluebird库不提供对此的支持。 - Pointy
1
window.URL 仅在 Edge(以及所有非 IE 浏览器)中可用。 - Andreas
看看 MDN 文档,它有支持表格 https://developer.mozilla.org/zh-CN/docs/Web/API/URL#Browser_compatibility - epascarello
10个回答

21

最后我通过这段代码来解决了这个问题:

function getQueryString() {
          var key = false, res = {}, itm = null;
          // get the query string without the ?
          var qs = location.search.substring(1);
          // check for the key as an argument
          if (arguments.length > 0 && arguments[0].length > 1)
            key = arguments[0];
          // make a regex pattern to grab key/value
          var pattern = /([^&=]+)=([^&]*)/g;
          // loop the items in the query string, either
          // find a match to the argument, or build an object
          // with key/value pairs
          while (itm = pattern.exec(qs)) {
            if (key !== false && decodeURIComponent(itm[1]) === key)
              return decodeURIComponent(itm[2]);
            else if (key === false)
              res[decodeURIComponent(itm[1])] = decodeURIComponent(itm[2]);
          }

          return key === false ? res : null;
}

...

        var api = getQueryString('api');

我忘记在哪里找到这个,但它正如我所需。


15

IE浏览器不支持URL。您需要添加一个polyfill来解决。


1
我该如何做?有没有演示? - CandleCoder
9
在我的情况下,添加<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>效果最佳。 - Arno van Oordt
我通过在页面头部添加以下一行代码解决了问题: <script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=URL"></script> - Marco Muciño

12

如果有人感兴趣,我一直在使用的另一种解决方案是:

function getParameterByName(name) {
  name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
      results = regex.exec(location.search);
  return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

getParameterByName('api');

太棒了!对我有用! - CAMD_3441

7
添加polyfill CDN脚本
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

5

该方法不受IE支持。

请参见https://developer.mozilla.org/en-US/docs/Web/API/URL#AutoCompatibilityTable

你应该使用像jquery deparam这样的库,或者使用String.split()方法检索参数,或者使用我制作的此函数:

function decodeUriComponentWithSpace (component) {
    return decodeURIComponent(component.replace(/\+/g, '%20'))
  }

  // type : 'hash', 'search' or 'both'
  function getLocationParameters (location, type) {
    if (type !== 'hash' && type !== 'search' && type !== 'both') {
      throw 'getLocationParameters expect argument 2 "type" to be "hash", "search" or "both"'
    }

    let searchString = typeof location.search === 'undefined' ? '' : location.search.substr(1)
    let hashString = typeof location.hash === 'undefined' ? '' : location.hash.substr(1)
    let queries = []
    if (type === 'search' || type === 'both') {
      queries = queries.concat(searchString.split('&'))
    }
    if (type === 'hash' || type === 'both') {
      queries = queries.concat(hashString.split('&'))
    }

    let params = {}
    let pair

    for (let i = 0; i < queries.length; i++) {
      if (queries[i] !== '') {
        pair = queries[i].split('=')
        params[this.decodeUriComponentWithSpace(pair[0])] = this.decodeUriComponentWithSpace(pair[1])
      }
    }
    return params
}

   // TEST: 
window.location.hash = 'test=a&test2=b'
console.log(getLocationParameters(window.location, 'both'))


4

纯Javascript解决方案,因此您可以在不使用polyfills的情况下在IE中运行它:

   function getUrlVars() {
        var vars = {};
        var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
            vars[key] = value;
        });
        return vars;
    }

这篇文章来自于这个页面:https://html-online.com/articles/get-url-parameters-javascript/


3
为了我的项目目的,我创建了这个脚本,我认为它也适用于您或其他遇到IE11和URL方法支持不足问题的人。
        /* Polyfill URL method IE 11 */

        // ES5

        if (typeof window.URL !== 'function') {
            window.URL = function (url) {
                var protocol = url.split('//')[0],
                    comps = url.split('#')[0].replace(/^(https\:\/\/|http\:\/\/)|(\/)$/g, '').split('/'),
                    host = comps[0],
                    search = comps[comps.length - 1].split('?')[1],
                    tmp = host.split(':'),
                    port = tmp[1],
                    hostname = tmp[0];

                search = typeof search !== 'undefined' ? '?' + search : '';

                var params = search
                    .slice(1)
                    .split('&')
                    .map(function (p) { return p.split('='); })
                    .reduce(function (p, c) {
                        var parts = c.split('=', 2).map(function (param) { return decodeURIComponent(param); });
                        if (parts.length == 0 || parts[0] != param) return (p instanceof Array) && !asArray ? null : p;
                        return asArray ? p.concat(parts.concat(true)[1]) : parts.concat(true)[1];
                    }, []);

                return {
                    hash: url.indexOf('#') > -1 ? url.substring(url.indexOf('#')) : '',
                    protocol: protocol,
                    host: host,
                    hostname: hostname,
                    href: url,
                    pathname: '/' + comps.splice(1).map(function (o) { return /\?/.test(o) ? o.split('?')[0] : o; }).join('/'),
                    search: search,
                    origin: protocol + '//' + host,
                    port: typeof port !== 'undefined' ? port : '',
                    searchParams: {
                        get: function(p) {
                            return p in params? params[p] : ''
                        },
                        getAll: function(){ return params; }
                    }
                };
            }
        }

        // ES6, in case of using Babel in a project

        if( typeof window.URL !== 'function' ){
            window.URL = function(url){
                let protocol = url.split('//')[0],
                    comps = url.split('#')[0].replace(/^(https\:\/\/|http\:\/\/)|(\/)$/g, '').split('/'),
                    host = comps[0],
                    search = comps[comps.length - 1].split('?')[1],
                    tmp = host.split(':'), 
                    port = tmp[1], 
                    hostname = tmp[0];

                search = typeof search !== 'undefined'? '?' + search : '';

                const params = search
                                    .slice(1)
                                    .split('&')
                                    .map(p => p.split('='))
                                    .reduce((obj, pair) => {
                                        const [key, value] = pair.map(decodeURIComponent);
                                        return ({ ...obj, [key]: value })
                                    }, {});

                return {
                    hash: url.indexOf('#') > -1? url.substring(url.indexOf('#')) : '',
                    protocol,
                    host,
                    hostname,
                    href: url,
                    pathname: '/' + comps.splice(1).map(function(o){ return /\?/.test(o)? o.split('?')[0] : o; }).join('/'),
                    search,
                    origin: protocol + '//' + host,
                    port: typeof port !== 'undefined'? port : '',
                    searchParams: {
                        get: p => p in params? params[p] : '',
                        getAll: () => params
                    }
                };
            }
        }
        /* Polyfill IE 11 end */

        new URL('http://localhost:8080/?a=1&b=3&c=z#123').searchParams.get('c'); // this will return "z"

但如果这个方法对你不起作用的话,你可以从这个网址中获取完全支持和填充的函数:

https://www.npmjs.com/package/url-polyfill


我个人认为这是最好的答案,谢谢。 - luciomonter

2
这里是另一个特定于URL API的polyfill,旨在与现代浏览器完全相同,并且仅在需要时运行。这样,您无需使用单独的函数,一旦决定停止支持IE,该函数将变得过时。
代码如下: <script src="https://gist.github.com/ryangoree/def0a520ed43c6c465d9a6518161bc7c.js"></script> Gist页面: https://gist.github.com/ryangoree/def0a520ed43c6c465d9a6518161bc7c

1
修改@ales的代码以获取特定参数的值。默认值设置为false
function getUrlVars(index) {
  var vars = {};
  window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (
    m,
    key,
    value
  ) {
    vars[key] = value;
  });

  if (index) {
    return vars[index] || false;
  }
  return vars;
}

0
我需要这样一个,然后又不需要了 :). 所以我会在这里发布它。
var urlRegex = /(.*:)\/\/(.*?)(\/.*?)(\?.*?|#.*?|$)(#.*|$)/

function parseUrl(url) {
  var parts = urlRegex.exec(url)
  var search = parts[4]
  var hash = parts[5]
  if (!search.startsWith('?')) {
    hash = search
    search = ''
  }
  if (!hash.startsWith('#')) {
    hash = ''
  }
  return {
    protocol: parts[1],
    host: parts[2],
    pathname: parts[3],
    search,
    hash,
    searchParams: search
      .replace(/^\?/, '')
      .split('&')
      .reduce((params, kv) => {
          var kvPair = kv.split('=')
          params[kvPair[0]] = kvPair[1]
          return params
        }, {})
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接