parseUri:URL divididas en JavaScript

Actualización: La siguiente publicación está desactualizada. Ver parseUri 1.2 para la última y mejor versión.

Por diversión, pasé los 10 minutos necesarios para convertir mi UDF ColdFusion parseUri() en una función de JavaScript.

Para aquellos que aún no lo han visto, repetiré mi explicación de la otra publicación…

parseUri() divide cualquier URI bien formado en sus partes (todas son opcionales ). Tenga en cuenta que todas las partes se dividen con una sola expresión regular usando referencias inversas, y todas las agrupaciones que no contienen partes de URI completas no se capturan. Mi parte favorita de esta función es su sólido soporte para dividir la ruta del directorio y el nombre del archivo (admite directorios con puntos y sin una barra invertida al final), que no he visto coincidir en otros analizadores de URI. Dado que la función devuelve un objeto, puede hacer, por ejemplo, parseUri(uri).anchor , etc.

Debo señalar que, por diseño, esta función no intenta validar el URI que recibe, ya que eso limitaría su flexibilidad. En mi opinión, la validación es un proceso completamente independiente que debe ocurrir antes o después de dividir un URI en sus partes.

Esta función no tiene dependencias y debería funcionar entre navegadores. Ha sido probado en IE 5.5–7, Firefox 2 y Opera 9.

/* parseUri JS v0.1.1, by Steven Levithan <http://stevenlevithan.com>
Splits any well-formed URI into the following parts (all are optional):
----------------------
- source (since the exec method returns the entire match as key 0, we might as well use it)
- protocol (i.e., scheme)
- authority (includes both the domain and port)
  - domain (i.e., host; can be an IP address)
  - port
- path (includes both the directory path and filename)
  - directoryPath (supports directories with periods, and without a trailing backslash)
  - fileName
- query (does not include the leading question mark)
- anchor (i.e., fragment) */
function parseUri(sourceUri){
	var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"],
		uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri),
		uri = {};
	
	for(var i = 0; i < 10; i++){
		uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
	}
	
	/* Always end directoryPath with a trailing backslash if a path was present in the source URI
	Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key */
	if(uri.directoryPath.length > 0){
		uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
	}
	
	return uri;
}

Pruébalo.

¿Hay algún analizador de URI más ligero y malo por ahí? 🙂

Editar: Actualmente, esta función no admite URI que incluyan un nombre de usuario o un par de nombre de usuario/contraseña (por ejemplo, "http://usuario:contraseñ[email protected]/"). No me importó esto cuando originalmente escribí el ColdFusion UDF en el que se basa, ya que nunca uso tales URI. Sin embargo, desde que lancé esto, siento que el apoyo debería estar allí. Sería fácil admitir dichos URI y dividir adecuadamente las partes. Lo que tomaría más tiempo es configurar una lista grande y apropiada de todo tipo de URI (tanto bien formados como no) para volver a probar la función. Sin embargo, si las personas dejan comentarios solicitando apoyo, continuaré y lo agregaré.