derek-watson / jsuri Goto Github PK
View Code? Open in Web Editor NEWUri parsing and manipulation for node.js and the browser.
License: MIT License
Uri parsing and manipulation for node.js and the browser.
License: MIT License
addQueryParam and replaceQueryParam do not encode the values passed.
I think they should.
Here is a simple example:
u = new Uri('http://example.com');
u.addQueryParam('email', '[email protected]');
u.clone().host() === u.host() // False?!
Because the query parameter is not escaped, @ is directly inserted into toString output, which then is mistreated as a special character in urls.
Perhaphs the proper solution is to escape query parameters on output, but when I added encodeURIComponent to Query.toString, it seems to have been called five times.
I couldn't figure it out.
Could you please take a look at it?
Offtopic: consider removing a minified version of the library from the versioning. I would have submitted a pull request, but I don't have the build tools that you are using and I don't want to leave the minified version outdated.
I am already using this library and would like to request the following feature.
=== Feature request ===
Details: Function to get an array of directories.
Example: http://example.com/dir1/dir2/dir3/index.html?q1=v1 => [dir1, dir2, dir3]
Contribution: If it is difficult to add this future in the near future, I am willing to make the contribution.
*Not as important, but a function to get the file name and file extension separately would be useful.
Thank you.
The README says query().params
should give an array of key/values but the property is undefined and seems to be only bound locally as parseQuery
, is this intended?
Hope this helps!
I want go get the value of a url query:
the url in the browser: domain.com/aare-wetter?city=biel
var currentParamValue = new URI().getQueryParamValue('city') ;
console.log(currentParamValue);
this returns:
TypeError: (new _urijs2.default(...)).getQueryParamValue is not a function
But all other jsuri things are working. What's the catch here?
Would be nice to be able to pass a flag to Uri constructor to set strictMode.
Could getQueryParamValue
ignore case sensitive? So these will return the same result:
uri.getQueryParamValue("productId")
uri.getQueryParamValue("ProductId")
uri.getQueryParamValue("productid")
uri.getQueryParamValue("PRODUCTID")
I'm looking into this and also "allmarkedup / jQuery-URL-Parser". One of the neat things in your plugin is able to construct url part-by-part instead of whole path string.
But dont see any method to process segment? Is there an easy way to do it?
Like parsing the segment in "allmarkedup / jQuery-URL-Parser" is nice. Also able construct the URL use clone and the adding segments is also cool as well. The way likes “addQueryParam”
Like adding the following methods to manipulate segments?
//return segment(s)
segment(index) - no index ==> all
//add or delete segment(s)
pushSegment()
popSegment(),
insertSegment (index),
deleteSegement(index)
var baseUri = new Uri('http://localhost/');
baseUri.clone().pushSegment('seg1'); // http://localhost/seg1/
or
baseUri.clone().pushSegment(['seg1', ‘seg2’]); // http://localhost/seg1/seg2/
I see we've added support for '@' in URLs. Could that make a v1.4.0 and a new package on NPM?
There is a change between version v1.1.1 and v1.3 that breaks compatibility.
In this example:
new Uri("http://localhost?myparam=toto+titi")
The "+" should be parsed as a space since in this form, the parameters are encoded but now it parses as an actual plus sign (%2B).
Expected behaviour (one of the two) :
new Uri("http://localhost?myparam=toto+titi").toString() === "http://localhost?myparam=toto%20titi"
or
new Uri("http://localhost?myparam=toto+titi").toString() === "http://localhost?myparam=toto+titi"
Current (wrong) behaviour:
new Uri("http://localhost?myparam=toto+titi").toString() === "http://localhost?myparam=toto%2Btiti"
The library has the correct behaviour in this case and this should not change:
new Uri( "http://localhost").replaceQueryParam("myparam", "toto+titi" ).toString() ===
"http://localhost/?myparam=toto%2Btiti"
Further information:
This "+" thing seems to be used by modern browser only when posting form as get (urlencoredform). It is however also used in the good old java api URLEncoder.
So users probably affected by this bugs are those interacting with java (URLEncoder) and Jersey's URIBuilder api and those using the library for decoding current page query parameters. (Ex: new Uri( window.location ) )
Even more information:
If you want to laugh (or cry): http://unixpapa.com/js/querystring.html
Hey, thanks for the great piece of code! I came across a problem when using toString
on an already encoded parameter.
new Uri("www.hello.com?q=1&anotherurl=http%3A%2F%2Fsite.com").toString()
// "www.hello.com/?q=1&anotherurl=http%253A%252F%252Fsite.com"
toString
gets the query part from the query
function, where I found encodeURIComponent
was causing the problem in my case. I figured a way to solve this is to decode and then encode again. I'm not sure whether this is bad practice or not. This did not break any other things for me, but I didn't run tests.
// Inside Uri.prototype.query
s += encodeURIComponent(decodeURIComponent(param[1]));
//s += encodeURIComponent((param[1]));
There:
new Uri("www.hello.com?q=1&anotherurl=http%3A%2F%2Fsite.com").toString()
// "www.hello.com/?q=1&anotherurl=http%3A%2F%2Fsite.com" yay
I'm not sure this is debatable (though URI.js does it) that adding query string parameters can just have a single value - for example "&link" and not necessarily "&link=true"
If you pass only one arg to jsUri addQueryParameter you get the worst possible outcome: "&link="
But I this should produce just "&link"
new Uri(url).addQueryParam('link').toString()
I'm using requirejs and the module does not register. Maybe I'm doing something wrong. I copied jquery module inclusion code into uri.js and it worked for me. You may want to add it to the lib.
/**
* export via CommonJS, otherwise leak a global
*/
if (typeof module === 'undefined') {
global.Uri = Uri;
if ( typeof define === "function" && define.amd ) {
define( "jsuri", [], function () { return Uri; } );
}
} else {
module.exports = Uri;
}
excerpt from jquery.js showing an example of this module inclusion logic:
if ( typeof module === "object" && module && typeof module.exports === "object" ) {
// Expose jQuery as module.exports in loaders that implement the Node
// module pattern (including browserify). Do not create the global, since
// the user will be storing it themselves locally, and globals are frowned
// upon in the Node module world.
module.exports = jQuery;
} else {
// Otherwise expose jQuery to the global object as usual
window.jQuery = window.$ = jQuery;
// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function () { return jQuery; } );
}
}
Derek - If you can include the minified version that will be great; then dont need to include all the tools to build it.
Thanks
Have you considered freshening up the API with ES5 Properties? I'll take the readme and offer a proposal of what could be done with it:
Pass any URL into the constructor:
var uri = new Uri('http://user:[email protected]:81/index.html?q=books#fragment')
Use property methods to get at the various parts:
uri.protocol // http
uri.userInfo // user:pass
uri.host // www.test.com
uri.port // 81
uri.path // /index.html
uri.query // q=books
uri.anchor // fragment
Property methods accept an optional value to set:
uri.protocol = 'https'
uri.toString() // https://user:[email protected]:81/index.html?q=books#fragment
uri.host = 'mydomain.com'
uri.toString() // https://user:[email protected]:81/index.html?q=books#fragment
ES5 Propery setter methods help you compose strings:
Object.assign(new Uri(), {
path: '/archives/1979/',
query: { page: 1 }
}).toString() // /archives/1979?page=1
Object.assign(new Uri(), {
path: '/index.html',
anchor: 'content',
host: 'www.test.com',
port: 8080,
userInfo: 'username:password',
protocol: 'https'
query: {
this: 'that',
some: 'thing'
}
}).toString() // https://username:[email protected]:8080/index.html?this=that&some=thing#content
especially with the query
changes, that would really freshen up the API. Poor souls that still need to support IE8 can stay on v1.
Thoughts?
s = s.replace('+', ' ');
should probably be:
s = s.replace(/+/g, ' ');
Hello Derek,
Thank you for the great library!
It seems like Uri
object only decodes query parameter values and keeps the rest of the segments "as is". Which leads to what seems to be inconsistent output for the most of its methods, especially .toString() and .query(). Please see the example below.
var encodedStr = encodeURI('http://ářé.html?ářé=ářé#ářé');
var url = new Uri(encodedStr);
url.host(); // encoded string;
url.getQueryParamValue('ářé'); // decoded string
url.queryPairs; // both query parameter name and value are decoded
url.query(); // mixed encoded and decoded characters
url.anchor(); // encoded string
url.toString(); // mixed encoded and decoded characters
It would be much easier for client code to consume the output of those methods if they always yield fully encoded or decoded strings.
I just test the lib after many others, and I see that it support ssh-like url for parsing.
However re-building an ssh-like url fail :
var u = new jsuri("[email protected]:path");
console.log(u.toString());
// [email protected]/path
Could you add the feature ?
I cannot find any other library that support it.
Thanks!
checking for an empty query parameter seems hard with the api.
I would have expected some doesExist()
uri.addQueryParam("pg", 0 ); // ?pg=
I don't see any build instructions, and I'm not handy with make
, so maybe I'm just missing something obvious, but I tried to make
and only got this:
jsUri$ make
Building ./dist/jsuri.js
/bin/sh: @@echo: command not found
make: *** [min] Error 127
What did I do wrong? :)
If a string with +
characters is supplied to represent a space then output will replace these with %20
Expressed in test form below
it('Uses + for spaces if part of supplied', function(){
var originalLink = 'http://www.example.com/example.html?var=a+b';
var u = new Uri( originalLink );
assert.equal( u.toString(), originalLink)
})
Use case: one of our uses for jsUri is to make a "prettified" compact version of user-supplied link by stripping out information extraneous to display such as ( but not limited to ) protocol. Re-encoding the space characters with a different symbol can be confusing.
Hi,
I may havea special case, but I'm using Uri.js to generate url for merge tags for news letters.
For example, with mailchimp, I return something like: http://mywebsite.com/?param=*|EMAIL|*
And I got %7CEMAIL%7C instead of |EMAIL|.
I suggest to change line to 435 to return decodeURI(s); instead of return s;
Worked for me ;-)
Within the last year, the JS community has converted almost all of their build systems over to Grunt, and rightly so given the extensive and rapidly growing community-driven plugin availability.
Working on jsUri has been my first experience with Jake but I definitely find its capabilities and portability lackluster compared to Grunt. I'd like to switch it over wwhen we can find some time.
so i've got a link through which I need to open my app. the link has some query parameters, which I need for the app. I use the url.path() method to check if the correct url has triggered the method. On android this url.path() method works fine and I get the correct url. but on ios it always returns /.
Any help would be appreciated.
Am I missing something, or is there no way to find the keys used in the query string? The current API is great if you know what to expect, but in my case, I don't.
I'll probably send a pull request shortly, but before I do: have I missed it? Or is this left out intentionally for some reason?
new Uri('http://www.abcd.com/a@Beltwy').host()
Will yield "Beltwy"
new Uri('http://www.abcd.com/aBeltwy').host()
Will yield "www.abcd.com" ...
Might actually be an invalid url , but should still return the right host
I very much hope you don't see the question as trolling- it's an honest question.
I see that URI.js has many more Github stars, and have trouble seeing the differences between you two.
I'm sure each has pros and cons, but they aren't listed in the README- any thoughts?
Thanks,
James
according to README.md
uri.query() should not begin with ?
, but it does.
test case here: http://aralejs.org/gallery/?grep=jsuri
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.