jerrybendy / url-search-params-polyfill Goto Github PK
View Code? Open in Web Editor NEWa simple polyfill for javascript URLSearchParams
License: MIT License
a simple polyfill for javascript URLSearchParams
License: MIT License
I am using the below code to get the url params. It is working fine in Chrome but not in EDGE & IE11. My URL has special characters in the query string for ex: http://localhost:8080/data/api?exp=$%^^%%^^*(*&
try {
let urlParams = new URLSearchParams(window.location.search);
} catch (err) {
console.log(err)
}
Please add a GitHub release tag for non-NPM usage
Used this library in one of my projects, and felt like giving back a little :) I noticed that the following sentence in the README file contains a few grammar mistakes:
Via the data of caniuse, there are many browsers support fetch but URLSearchParams.
I can submit a pull request so that it reads:
Via the data of caniuse, there are many browsers that support fetch but not URLSearchParams.
Thanks for the library and happy hacking!
I am getting client-side bug reports of the error above, at line 15. So far I have only seen this on Chrome 69 on Windows 10
Javascript error:
Expected identifier
Internet Explorer Version 11.0.9600.18738
If I delete the following and everything after then the error goes away:
/**
* Deletes the given search parameter, and its associated value,
* from the list of all search parameters.
*
* @param {string} name
*/
prototype.delete = function(name) {
delete this [__URLSearchParams__] [name];
};
const params = new URLSearchParams('?demo');
params.has('demo'); // => false; should be true
params.get('demo'); // => null; should be an empty string
Array.from(params.keys()); // => []; should be ['demo']
This was also mentioned in a closed issue: #51 (comment)
repro: https://codesandbox.io/s/suspicious-feather-0izb87?file=/src/index.js
According MDN, the following usages of the constructor should be equivalent:
// Pass in a sequence
var params3 = new URLSearchParams([["foo", 1],["bar", 2]]);
// Pass in a record
var params4 = new URLSearchParams({"foo" : 1 , "bar" : 2});
However, given the first ('sequence') style, the constructor will produce the following:
'0=a%2C1&1=b%2C2'
(encoded '0=a,1&1=b,2')
Hey guys, I think I may have found a bug in a Safari's 10.1 native URLSearchParams implementation. Because of the fact the URLSearchParams
and Proxy
is supported in Safari 10.1 the polyfill still uses a faulty native implementation. (https://github.com/jerrybendy/url-search-params-polyfill/blob/master/index.js#L125).
OS: MacOS Sierra
Browser: Safari 10.1
When typing in a dev console of virtually every browser:
new URLSearchParams("s=%2B").get("s") // "+"
In Safari 10.1 it yields a space.
new URLSearchParams("s=%2B").get("s") // " "
The solution is to to fully replace native URLSearchParams with the polyfill, because of Proxy
the polyfill still uses a faulty native implementation. I've prepared a pull request for it.
#21
While testing we noticed that the URLSearchParams in Chrome 50 in Android was failing. So the polyfill wasn't working for us. Just a note for more investigation.
browser : ie9
error message: params error
Hi!
I am trying to polyfill URLSearchParams so that i can use "react-query-params" (version 1.0.7) also in Firefox 24.
But when using this polyfill I still get an error.
The error can be reproduced with that code:
var urlSearch = new URLSearchParams(window.location.search);
var _iterator = urlSearch[Symbol.iterator]()
I get the error:
TypeError: urlSearch[Symbol.iterator] is not a function
BR
Thanks for this nice library.
I know MIT is mentioned as license, but I believe you need to include the license text mentioning the copyright owner, etc. to actually license the code under MIT.
Using version 2.0.3, in IE/Safari, the following occurs:
> const params = {
anArray: [1, 2, 3, 4]
};
> const searchParams = new URLSearchParams(params);
> console.log(searchParams.get('anArray');
'[1, 2, 3, 4]'
The behaviour seen in the browser based implementations (eg. Chrome) is to remove those brackets by the time it's in the URLSearchParam object. This causes HTTP requests to other services to include URL encoded brackets in the query string, and often fail unless handled server-side.
Using v7.0.1
Trying to parse a URL with hasOwnProperty
as a search param (for example http://mysite.com?hasOwnParam=abcde
) results in a TypeError
with the following trace. This is case sensitive, so hasownproperty=abcde
works fine.
I'm calling: const params = URLSearchParams(searchString)
This was caught by bugsnag, and we are not using this param anywhere. I suspect it's some kind of attempted code injection attack, or something of that sort.
TypeError: dict[name].push is not a function
at appendTo (/code/enterprisepaxfe/node_modules/url-search-params-polyfill/index.js:326:24)
at parseToDict (/code/enterprisepaxfe/node_modules/url-search-params-polyfill/index.js:307:21)
at URLSearchParamsPolyfill (/code/enterprisepaxfe/node_modules/url-search-params-polyfill/index.js:44:38)
at URLSearchParams (/code/enterprisepaxfe/.dist/server/webpack:/src/components/VsmRouteState/index.jsx:39:40)
at Route.render (/code/enterprisepaxfe/node_modules/react-router/Route.js:124:32)
at processChild (/code/enterprisepaxfe/node_modules/react-dom/cjs/react-dom-server.node.development.js:2207:18)
at resolve (/code/enterprisepaxfe/node_modules/react-dom/cjs/react-dom-server.node.development.js:2064:5)
at ReactDOMServerRenderer.render (/code/enterprisepaxfe/node_modules/react-dom/cjs/react-dom-server.node.development.js:2349:22)
at ReactDOMServerRenderer.read (/code/enterprisepaxfe/node_modules/react-dom/cjs/react-dom-server.node.development.js:2323:19)
at Object.renderToString (/code/enterprisepaxfe/node_modules/react-dom/cjs/react-dom-server.node.development.js:2695:25)
at renderToString (/code/enterprisepaxfe/.dist/server/webpack:/src/server/renderBundle.jsx:56:30)
at /code/enterprisepaxfe/.dist/server/webpack:/src/server/index.js:64:17
at Layer.handle [as handle_request] (/code/enterprisepaxfe/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/code/enterprisepaxfe/node_modules/express/lib/router/index.js:317:13)
at /code/enterprisepaxfe/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/code/enterprisepaxfe/node_modules/express/lib/router/index.js:335:12)
We switched from https://github.com/ungap/url-search-params to this polyfill, but we found problems in some browsers related to that switch.
The toString method doesn't work well, in some browsers, we see GET request logged like this:
checkout?order-candidate-id%2Cabc
where it should be
checkout?order-candidate-id=abc
Top 5 User agents where this happens:
I have been using this library to use URLSearchParams in React Native without problems.
After updating React Native to version 0.59, this library no longer works because the people at FB have decided to provide a prototype for the get() function. There prototype simply returns that the get() function is not implemented.
Since the get() function is tested for presence and if present, the library returns the native function, then the library becomes useless.
Here's React Native implementation of URLSearchParams
https://github.com/facebook/react-native/blob/master/Libraries/Blob/URL.js
I know that this is not necessarily an issue with this library but it is important to be aware that it cannot be used in a React Native app unless it gets fixed.
No error but just won't in IE11
Hello,
according to https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams, only firefox has full URLSearchParams
support. The other browsers have only a basic support or no support at. With the second group everything is ok, but with the first group, even after appling this polyfill, the following test will fail:
new URLSearchParams({foo: 'bar'}) == 'foo=bar'
I sugest to replace in index.js
:
if (self.URLSearchParams) {
return;
}
with
try {
if (self.URLSearchParams && new (self.URLSearchParams)({foo: 'bar'}) == 'foo=bar') {
return;
}
} catch (err) {
// we'd better polyfill this case too
}
@jerrybendy if you are agree, I can create a pull request.
Hi there,
We recently upgraded to the newer version 8.2.3 but since upgrading, all POST requests using URL Search Params seem to be sending the data across in JSON as opposed to Form Data like they were previously. Because of this, it causes the browser to break in Safari and post an error.
I was only able to catch this by going through each of my dependencies and finding the root cause.
Thanks in advance but will hardcode our version to 8.1.1 for now as this seems to keep things working.
I have some code along the lines of
let params = new URLSearchParams(...);
let opts = {
method: "post",
body: params,
credential: "same-origin",
};
fetch(url, opts).then(...);
I used this polyfill to get the URLSearchParams constructor working in Edge. This is fine, but in Chrome and Firefox, setting the POST body to a URLSearchParams instance also sets the Content-Type
header to application/x-www-form-urlencoded
, per the Fetch spec. When using the polyfill, I have to manually set this header value in each Fetch call, using headers
in the options object.
It would be great if the polyfill could hook/patch the fetch
method to set this value automatically, but I suspect this won't be feasible. In that case, the documentation should be updated to note this additional usage requirement. Ideally, the library could expose a feature test function or a global variable that we could test against before manually setting headers:
if (__URLSEARCHPARAMS_USE_POLYFILL){
opts.headers = {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"}
}
rather than always overriding the automatically-determined (in fully compliant browsers) content type.
I have been using this library to use URLSearchParams in AEM project without problems.
When we are using it on mobile device getting TypeError with .sort() method , even those we are not using sort method anywhere in our project.
Check out the code at line no. 184.
According to MDN:
An object implementing URLSearchParams can directly be used in a for...of structure, instead of entries(): for (var p of mySearchParams) is equivalent to for (var p of mySearchParams.entries()).
Thus, I expect this to work:
const params = new URLSearchParams(queryString); // polyfilled with url-search-params-polyfill
for (const param of params) {
console.log(params); // -> [key, value]
}
However this will throw an error:
undefined is not a constructor (evaluating 'params[Symbol.iterator]()')
Furthermore, there is no entries()
method so I cannot fall back to this.
What browsers and versions will this work with?
When I am trying this in ie11 I got the following:
[Vue warn]: Error in created hook: "ReferenceError: "URLSearchParams" is undefined"
[object Error]{description: ""URLSearchP...", message: ""URLSearchP...", name: "ReferenceEr...", number: -2146823279, stack: "ReferenceEr..."}
(expandable to the Object)
I really don't know what i am doing wrong.
I am using Vue, Typescript, Vue Bootstrap, Vuex, Vue Router.
I am using URLSearchParams like this in my main.ts
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import BootstrapVue from 'bootstrap-vue';
import VueMoment from 'vue-moment';
import Datepicker from 'vuejs-datepicker';
import GridLoader from 'vue-spinner/src/GridLoader.vue';
import 'url-search-params-polyfill';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
[…]
const app = new Vue({
data: { loading: false },
router,
store,
created() {
setParams();
},
render: (h) => h(App),
}).$mount('#app');
[…]
function setParams() {
const urlParams = new URLSearchParams(window.location.search);
// already failed
[…]
}
Originally posted by @Garionion in #30 (comment)
I am not sure if this is problem with the polyfill, but when I include it in babel.config.js, it causes the build to fail.
module.exports = {
presets: [
['@vue/app', {
polyfills:
[
'url-search-params-polyfill'
]
}]
]
}
This results in quite cryptic failure I have problem understanding.
./src/main.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
TypeError: [BABEL] /opt/ondb/dev-front/ondb-frontend/src/main.js: Cannot read property 'chrome' of undefined (While processing: "/opt/ondb/dev-front/ondb-frontend/node_modules/@vue/babel-preset-app/index.js")
at targetEnvironments.filter.environment (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/preset-env/lib/index.js:75:16)
at Array.filter (<anonymous>)
at isPluginRequired (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/preset-env/lib/index.js:74:56)
at includes.filter.item (/opt/ondb/dev-front/ondb-frontend/node_modules/@vue/babel-preset-app/index.js:26:12)
at Array.filter (<anonymous>)
at getPolyfills (/opt/ondb/dev-front/ondb-frontend/node_modules/@vue/babel-preset-app/index.js:25:19)
at module.exports (/opt/ondb/dev-front/ondb-frontend/node_modules/@vue/babel-preset-app/index.js:106:17)
at loadDescriptor (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/core/lib/config/full.js:165:14)
at cachedFunction (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/core/lib/config/caching.js:33:19)
at loadPresetDescriptor (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/core/lib/config/full.js:235:63)
at config.presets.reduce (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/core/lib/config/full.js:77:21)
at Array.reduce (<anonymous>)
at recurseDescriptors (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/core/lib/config/full.js:74:38)
at loadFullConfig (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/core/lib/config/full.js:108:6)
at process.nextTick (/opt/ondb/dev-front/ondb-frontend/node_modules/@babel/core/lib/transform.js:28:33)
at process._tickCallback (internal/process/next_tick.js:61:11)
We are occasionally seeing this error:
TypeError Cannot set property URLSearchParams of [object Object] which has only a getter
https://polyfill.io/v3/polyfill.min.js:3:11759
https://polyfill.io/v3/polyfill.min.js:3:11762
https://polyfill.io/v3/polyfill.min.js:3:12205
https://polyfill.io/v3/polyfill.min.js:3:12215
It has been observed on the following browser versions:
browserName
Edge
browserVersion
18.17763.0
locale
en-GB
osName
Windows 10.0
time
2019-09-18T21:30:54.670Z
userAgent
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763
And also
browserName
Edge
browserVersion
16.16299.0
locale
en-US
osName
Windows 10.0
time
2019-09-18T17:19:16.278Z
userAgent
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299
Unfortunately we haven't been able to reliably reproduce it.
I came here because I noticed a major version upgrade from 4.0.1 to 5.0.0, indicating breaking changes, however the only thing in the release notes is "Fix ampersands encoding bug in Edge." Is this a breaking change, and if so what are the upgrade requirements?
If not, please adopt semver. Specifically, this minor bug fix should have been released as version 4.0.2. This would save anyone using your package a tremendous amount of time in determining upgrade requirements and compatibility.
Thank you!
Specifically, what are the differences between this library and https://github.com/WebReflection/url-search-params, which seems to be recommended by google here: https://developers.google.com/web/updates/2016/01/urlsearchparams. Can you explain a little bit about how this polyfill is different?
function encode(str) {
var replace = {
'!': '%21',
"'": '%27',
'(': '%28',
')': '%29',
'~': '%7E',
'%20': '+',
'%00': '\x00'
};
return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function(match) {
return replace[match];
});
}
Why not use encodeuri?
Instead, the above specific characters are processed separately
Js code snippet to reproduce:
let body = new URLSearchParams("&b=555");
console.log(body.toString());
fetch('/test.php', { method : 'POST', body })
.then(response => response.json())
.then(console.log);
test.php
<?php
echo json_encode($_POST);
Result with native chrome URLSearchParams (1.2.0) :
"b=555"
Object {b: "555"}
With polyfilled URLSearchParams (1.3.0):
"b=555"
[]
Tested on google chrome 59 linux
is missing
we use this to simulate a form post. In chrome, where the polyfill is not loaded, I can pass a url as a parameter:
params.set('target', '/url/as/a/parameter');
in the network tab, I see in the request body:
target: /url/as/a/parameter
but in IE 11, which needs the polyfill, I see:
target: %2Furl%2Fas%2Fa%2Fparameter
Thank you for this polyfill. Exactly what I needed, because other polyfills didn't work for me. 👍
URL instance supports searchParams
member which is URLSearchParams
. It will be great to support this here.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.