mikhus / domurl Goto Github PK
View Code? Open in Web Editor NEWLightweight URL manipulation with JavaScript
License: MIT License
Lightweight URL manipulation with JavaScript
License: MIT License
Example: https://codesandbox.io/s/1wzz6nr0j4?fontsize=14
queryLength is not searching the query, but is searching the whole URL object instead. This is also causing isEmptyQuery to return an incorrect value.
This should be an easy fix, but I wanted to confirm that this is indeed a bug before going ahead and making a PR for it.
Can I get url parameters as object or variables with valu?
This u.query.a = [1, 2, 3];
creates a=1&a=2&a=3
while the correct is a[0]=1&a[1]=2&a[2]=3
The currently generated URL can lead to query overload, which depends on the server (apache, lighttpd or Microsoft) understand differently. While the second one is the correct array GET structure.
In languages where associative array exists, the following is also valid:
For u.query.a = ['key1' => 1, 'key5' => 2, 'key3' => 3];
represented as a[key1]=1&a[key5]=2&a[key3]=3
, this is most probably represented in JS as an object like u.query.a = {"key1": 1, "key5": 2, "key3": 3};
.
Also, servers support multidimensional array/objects, which's not supported here.
u.query.a = [1, [2, 5], 3];
as a[0]=1&a[1][0]=2&a[1][1]=5&a[2]=3
u.query.a = {"key1": 1, "key5": [2, 5], "key3": 3};
as a[key1]=1&a[key5][0]=2&a[key5][1]=5&a[key3]=3
u.query.a = {"key1": 1, "key5": {"key1": 2, "key6": 5}, "key3": 3};
as a[key1]=1&a[key5][key1]=2&a[key5][key6]=5&a[key3]=3
Suggest the following addition:
main: [ "url.js" ]
Was looking for something similar to your library. I'm looking through the code and just want to confirm, this only allows you to update the object created by instantiating the class. This doesn't actually update the URL when changes to the class are made? If this is the case it would be interesting to add some HTML5 history support to update the actual URL when changes are made to the domurl object. Reading the description of the project I assumed this was what it actually did.
I'm going to be modifying the library for my own use, to update the URL, if you're interested I'll try to form a complete solution and submit a pull request when I'm done. If not I'll just add the stuff I need in my project.
Thanks for taking the time to make this thing and sharing it 👍
Hi,
I've found an issue when one of our scripts that use domurl was injected inside a srcdoc iframe.
That is an strange case, but I though It may be worth mentioning it.
Here there is a minimal example:
<!doctype html>
<html>
<body>
<iframe srcdoc='<script src="https://cdn.jsdelivr.net/npm/[email protected]/url.js" integrity="sha256-4NOatzFOPdRvADrRwu+TbGMS2LQNQ0ZEseTjM1sdFj4=" crossorigin="anonymous"></script><script>var url = new Url("/robots.txt");</script>'></iframe>
</body>
</html>
Output:
TypeError: getCurrUrl(...).match(...) is null
What do you think? It feels like something that should be "gracefully" handled? A bit difficult may be.
Thanks
IE omits the leading slash from the pathname. This happens when doing
link = document.createElement('a');
link.href = "/a/url"
// in IE
link.pathname == "a/url"
// in all other browsers
link.pathname == "/a/url"
easily reproducible in IE with
Url = require("domurl")
new Url("/a/url", true)
Possible fix: https://news.ycombinator.com/item?id=3939454
Hi,
When parsing an url with a query param named "count", the name "count" collides with the method "count" of the Query object, and the parameter count is being discarded as a side effect of this.
Hi @Mikhus
Your great work had been recommend being added in CDNJS.
However, we need tags for repo to specify points in history and mark release points.
It's helpful for users to know the version and status of repository, and would enable wider distribution of the library.
Would you please consider on using tags?
Thank you!
Piicksarn
#6428
This code gives proper result:
>>> new Url('http://localhost/?a=%3F').query.a
"?"
>>> new Url('http://localhost/?a=%3F').toString()
"http://localhost/?a=%3F"
And this does not decode query parameters, resulting in double-encoding when using toString()
:
>>> new Url('http://localhost/?a=%3f').query.a
"%3f"
>>> new Url('http://localhost/?a=%3f').toString()
"http://localhost/?a=%253f"
(Found in IE10)
new Url('//url-with-relative-protocol.co.uk/blah').toString();
// actual -> 'url-with-relative-protocol.co.uk/blah'
// expected 1 -> '//url-with-relative-protocol.co.uk/blah'
// expected 2 -> [current page's protocol] + '//url-with-relative-protocol.co.uk/blah'
In our company we are migrating away from bower in favor of npm registry. Could you publish the package on npm?
Even whitespaces are url-encoded... only the single quotation mark (') is not encoded url-compatible.
I've written a simple function that cleans some query strings out of any provide url string:
function sanitizeURL(url) { var url = new Url(url); if(url.query["reload"]) { delete url.query["reload"] } if(url.query["forceReload"]) { delete url.query["forceReload"] } if(url.query["device"]) { delete url.query["device"] } if(url.query["testwebid"]) { delete url.query["testwebid"] } if(url.query["testWebId"]) { delete url.query["testWebId"] } if(url.query["testWebID"]) { delete url.query["testWebID"] } if(url.query["timetravel"]) { delete url.query["timetravel"] } return url.toString(); }
but when I add run with a relative url string the whole pages path is returned:
sanitizeURL("SearchResults?search=new&make=Buick&year=2016&forceReload=true")
What's returned:
"file:///Volumes/Macintosh%20HD/Users/brooksg/SearchResults?search=new&make=Buick&year=2016"
Expecting:
"SearchResults?search=new&make=Buick&year=2016"
Is there anyway around this or is this a bug?
When init with url like this new Url('http://www.example.com/hello world here.jpg').toString()
returns: http://www.example.com/hello%2520world%2520here.jpg
expected result: 'http://www.example.com/hello%20world%20here.jpg'
Not sure why the space got encoded into %2520
When remove the protocol it works correctly:
new Url('www.example.com/hello world here.jpg').toString()
=> 'www.example.com/hello%20world%20here.jpg'
Some tools that use Bower expect a package to have versions associated with it. Bower can't find any versions for the jsurl package because there are no git tags pushed for this repo. See:
Please push a git tag for this project. See here for more information: http://stackoverflow.com/a/20055632
var url = new Url("localhost:9001");
console.log(url, '' + url);
Url {protocol: "localhost", host: "", port: "", path: "/9001", query: QueryString…}
hash:""
host:""
pass:""
path:"/9001"
port:""
protocol:"localhost"
query:QueryString
user:""
__proto__:Object
localhost:///9001
Is it possible to create url like this: a[]=1&a[]=2&a[]=3 ?
regards
Hello!
You didn't think about language support for TypeScript? I could write a file jsurl.d.ts, and push it to the DefinitelyTyped repository which would be a description of the library functions.
require('domurl')
Gives me ModuleNotFoundError in Module not found: Error: Cannot resolve module 'fs' in /node_modules/domurl
var a={q:1, w:"w2", e:{ea:"123qwe", eb:"345asd"}, f:["qw", "er", 12], g:[{zx:123, vv:345}, {zxc:1234, cvb:3455}] };
var u=new Url("https://us:[email protected]/path1/path2?" + decodeURIComponent($.param(a)) );
u.query.e should return {ea:"123qwe", eb:"345asd"}
Very nice peace of code, it will be cool and useful to add it as bower package!
Last paragraph of https://tools.ietf.org/html/rfc3986#section-3.3 says:
Aside from dot-segments in hierarchical paths, a path segment is
considered opaque by the generic syntax. URI producing applications
often use the reserved characters allowed in a segment to delimit
scheme-specific or dereference-handler-specific subcomponents. For
example, the semicolon (";") and equals ("=") reserved characters are
often used to delimit parameters and parameter values applicable to
that segment. The comma (",") reserved character is often used for
similar purposes. For example, one URI producer might use a segment
such as "name;v=1.1" to indicate a reference to version 1.1 of
"name", whereas another might use a segment such as "name,1.1" to
indicate the same. Parameter types may be defined by scheme-specific
semantics, but in most cases the syntax of a parameter is specific to
the implementation of the URI's dereferencing algorithm.
This means, these special characters can be present in path, carrying special information.
In other words, they are supposed to be escaped only if they are expected not to carry the special information, like if they appear in a directory name on the file-system.
On Chrome, these comparisons are all truthful:
String(new URL("http://example.com/alice=bob")) == "http://example.com/alice=bob"
String(new URL("http://example.com/alice;bob")) == "http://example.com/alice;bob"
String(new URL("http://example.com/alice,bob")) == "http://example.com/alice,bob"
I think domurl
should be able to parse and re-gen those values as well. Wdyt?
I dont know if it's the right behavior. I'm actually using backbone and the way to describe routes (like many front-end framework) is with hash like foo/1
which become foo%2F1
when using domurl to manipulate query parameters.
In MS Edge, if you pass a malformed url like http://Photo@
to the Url constructor of this library, you get a mysterious exception "A security problem occurred". You can see the same error by just running var link = document.createElement("a"); link.href = "http://Photot@"; link["protocol"];
in console. It would be better if domurl caught this and raised a more understandable error.
I installed the library and imported it to my srcipt by
import 'domurl';
however when I load page I get mentioned error in console. Tested on Firefox 75.0 on Windows.
var u2 = new Url("https://example.com/");
u2.query["computer"] = {};
u2.query["computer"]["desktop"] = "Mac";
alert(u2);
The result should be this...
https://example.com/?computer[desktop]=Mac
Instead, I get this...
https://example.com/?computer=%5Bobject%20Object%5D
Also, when I parse a URL that looks like....
https://example.com/?computer[desktop]=Mac
...Inspecting the object in the console should look like return something like...
Computer: Object
desktop: "Mac"
Instead I get this...
computer[desktop]: "Mac"
"desktop" isn't recognized as an object inside of "computer". "computer[desktop]" is simply used as the key like any other string.
When initializing with new Url()
, this module uses the current window.location.href
by default, and then caches it forever in the module's closure/namespace. After that, even when the window.location.href
changes, the module will still use the old/incorrect cached value on new Url()
invocations:
var url = new Url();
url.hash = "somehash";
window.location.href = url.toString()
var url2 = new Url();
url2.hash // empty, should be "somehash"
Also note that in apps using pushState (i.e. most SPAs these days), much more than the hash will change. The above is just one way to demonstrate the bug in a non-pushState navigation without causing a page reload.
Traditionally, +
sign has been treated as Space, b/c that's how x-www-form-urlencoded
prefers to encode a space in its values. (Maybe also names, I'm not sure at the moment.)
However, the Plus Sign should not be treated as Space outside of Query Params. Doing so would make parsing of URLs such as https://en.wikipedia.org/wiki/C++ incorrect.
Looks like the changes in 1a605a5 have made some of the decoding and encoding behaviors asymmetric.
First, a loop on a valid URL causes value-less params to get lost. So, this doesn't pass:
const urlString1 = "/?alice=123&bob=&carol";
const url1 = new Url(urlString1);
expect(String(url1)).toEqual(urlString1);
with error:
Expected: "/?alice=123&bob=&carol"
Received: "/?alice=123&bob="
After decoding, this does pass:
const urlString1 = "/?alice=123&bob=&carol";
const url1 = new Url(urlString1);
expect(url1.query["alice"]).toEqual("123");
expect(url1.query["bob"]).toEqual("");
expect(url1.query["carol"]).toBe(null);
expect(url1.query["dave"]).toBe(undefined);
So, the problem lays on the encoding side. With changing the encoding logic to:
undefined
, andnull
,.query
to reconstruct the URL would result in the original URL, hence passing the initial test.What do you think?
Hi, I'm trying to load UTM codes into the URL on page load; the alert pops up that it has successfully done so, but the URL in the browser doesn't reflect that... how do I do that?
I am calling the js file, then this is my script:
<script type="text/javascript"> var url = new Url('?utm_medium=dm&utm_source=cnst&utm_campaign=q114b&utm_content=ja14ml'); alert( url); </script>Thanks!
Levels of support can be like:
Specifically, (1) is very important when using the library on href
values, which can be intentionally kept as PRL, for better client support.
References:
What do you think?
Issues when square brackets are used in parameter name.
e,g it cannot handle:
/products/?items[]=e&items[]=f
It just see 'item[]' and 'item'
Variables with a value of undefined are included in the query string.
For example:
var url = new Url();
var url2 = new Url();
url2.clearQuery();
url2.query["var"] = url.query["var"];
ur2.query.toString()
If "var" doesn't exist in the query string, this will print out "var=undefined". Could undefined variables be ignored?
Is it possible to integrate something like this:
// URI Templates
URI.expand("/foo/{dir}/{file}", {
dir: "bar",
file: "world.html"
});
// -> /foo/bar/world.html
Attempt to parse the following URL causes the wrong result
var feed = new Url('https://www.google.com/calendar/feeds/test/private-t42423424234/full?start-index=1&max-results=20');
feed.toString() ->> returns
"https://www.google.com:443calendar/feeds/test/private-t42423424234/full?start-index=1&max-results=20"
There are two problems:
I have fixed it by changing toString() function to the following. Haven't tested it in all scenarios, by with full URL works fine
this.toString = function () {
return (
(this.protocol && (this.protocol + '://')) +
(this.user && (this.user + (this.pass && (':' + this.pass)) + '@')) +
(this.host && this.host) +
((this.port && !(this.port == 443 && this.protocol == 'https') && !(this.port == 80 && this.protocol == 'http')) ? this.port : '') +
(this.path && ('/' + this.path)) +
(this.query.toString() && ('?' + this.query)) +
(this.hash && ('#' + this.hash))
);
};
Does it work with RequireJS directly?
Try this out:
var url = new Url("http://example.com/some/path?a=b&c=test@someAnchor");
url.toString()
>>>"http://example.com%2Fsome%2Fpath%3Fa%3Db%26c%[email protected]/some/path?a=b&c=test%40someAnchor"
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.