url参数解析是web开发不可能绕开的环节。其中url地址有六部分组成,我们讨论的仅是query部分的解析。
组成部分:
<scheme>://<netloc>/<path>;<params>?<query>#<fragment>
分析地址:
let queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD"
ds=1%202+3 这个参数需要特别注意。 其中%20为空格,+需要同样为空格。现将各种语言的解析方法总结如下。
推荐的方法有: 方法1 ,方法5,方法6
const groupParamsByKey = (params) => [...params.entries()].reduce((acc, tuple) => {
const [key, val] = tuple;
if (acc.hasOwnProperty(key)) {
if (Array.isArray(acc[key])) {
acc[key] = [...acc[key], val]
} else {
acc[key] = [acc[key], val];
}
} else {
acc[key] = val;
}
return acc;
}, {});
let queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD"
let url = new URL(queryUrl);
const params = new URLSearchParams(url.search.substring(1));
let result = groupParamsByKey(params);
console.info(result);
// { appkey: 'quark_and', ds: [ '1', '1 2 3', '3', '中国' ] }
function parseUrl(r) {
if (!r) return !1;
r = r.replace(/&/g, "&");
var t = {};
t.query = r.replace(/([^?]+)\?/, function (r, e) {
return t.path = e, ""
}).replace(/#.*/, function (r) {
return t.hash = r, ""
});
t.params = {};
t.query.split("&").forEach(function (r, e) {
var n = r.split("=");
n[0] && (t.params[n[0]] = 1 < n.length ? decodeURIComponent(n[1]) : "")
});
return t
}
let queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD"
let result = parseUrl(queryUrl);
console.info(result["params"]);
//{ appkey: 'quark_and', ds: '中国' }
let queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD"
// queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3"
let url = new URL(queryUrl);
const search = url.search.substring(1);
console.info(JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) }));
let queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD"
queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3"
let url = new URL(queryUrl);
const search = url.search.substring(1);
let entry = Object.fromEntries(new URLSearchParams(search));
console.info(entry);
const querystring = require('querystring');
console.info(querystring.parse('appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD'));
官方的文档如下:
function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): ParsedUrlQuery
The querystring.parse() method parses a URL query string (str) into a collection of key and value pairs.
For example, the query string 'foo=bar&abc=xyz&abc=123' is parsed into:
{
foo: 'bar',
abc: ['xyz', '123']
}
let queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD"
let url = new URL(queryUrl);
const search = url.search.substring(1);
let result = search.slice(1).split('&').map(p => p.split('=')).reduce((obj, pair) => {
let [key, value] = pair.map(decodeURIComponent);
value = value.replace("+"," ");
if (obj.hasOwnProperty(key)){
obj[key] = [...obj[key],value];
}else{
obj[key] = value;
}
return obj;
}, {});
console.info(result);
直接使用默认的urllib模块是最好的方式。如果参数仅有一个值,也会是list结构,这个地方需要注意一下。
from urllib import parse
queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD"
urlparse = parse.urlparse(queryUrl)
params = parse.parse_qs(urlparse.query)
print(params)
# {'appkey': ['quark_and'], 'ds': ['1', '1 2 3', '3', '中国']}
java url 解析的方法与这个相同,可根据这个稍微修改下语法。
import com.alibaba.fastjson.JSONObject
import javax.servlet.http.HttpServletRequest
println(JSONObject.toJSONString(request.parameterMap))
for (x in request.getParameterValues("ds")){
println(x)
}
public static Map> splitQuery(URL url) throws UnsupportedEncodingException {
final Map> query_pairs = new LinkedHashMap>();
final String[] pairs = url.getQuery().split("&");
for (String pair : pairs) {
final int idx = pair.indexOf("=");
final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
if (!query_pairs.containsKey(key)) {
query_pairs.put(key, new LinkedList());
}
final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : "";
query_pairs.get(key).add(value);
}
return query_pairs;
}
public static void main(String[] args) throws MalformedURLException, UnsupportedEncodingException {
String queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD&ddd=";
System.out.println(splitQuery(new URL(queryUrl)));
}
import java.net.URL
import java.net.URLDecoder
import java.util.*
import kotlin.collections.LinkedHashMap
fun splitQuery(url: URL): Map> {
val queryPairs: MutableMap> = LinkedHashMap()
val pairs: List = url.query.split("&")
for (pair in pairs) {
val idx = pair.indexOf("=")
val key = if (idx > 0) URLDecoder.decode(pair.substring(0, idx), "UTF-8") else pair
if (!queryPairs.containsKey(key)) {
queryPairs[key] = LinkedList()
}
val value = if (idx > 0 && pair.length > idx + 1) URLDecoder.decode(pair.substring(idx + 1), "UTF-8") else ""
queryPairs[key]!!.add(value)
}
return queryPairs
}
fun main() {
val queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD&ddd="
println(splitQuery(URL(queryUrl)))
}
$queryUrl = "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD&ddd=";
//$query = explode('&', $_SERVER['QUERY_STRING']);
$query = explode('&', substr($queryUrl,strpos($queryUrl,"?") + 1));
$params = array();
foreach( $query as $param )
{
list($name, $value) = explode('=', $param, 2);
$params[urldecode($name)][] = urldecode($value);
}
$json = json_encode($params);
echo $json;
import (
"fmt"
"net/url"
)
func main() {
queryUrl := "https://userver-upaas.uc.cn/login?appkey=quark_and&ds=1&ds=1%202+3&ds=3&ds=%E4%B8%AD%E5%9B%BD&ddd="
parse, _ := url.Parse(queryUrl)
fmt.Println(parse.Query())
for key, value := range parse.Query() {
fmt.Println(key, value)
}
}
url 参数转换为对象的工具,在dejs站点有添加。