url多参数解析

url参数解析是web开发不可能绕开的环节。其中url地址有六部分组成,我们讨论的仅是query部分的解析。

组成部分:

<scheme>://<netloc>/<path>;<params>?<query>#<fragment>

url组成规范

分析地址:

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为空格,+需要同样为空格。现将各种语言的解析方法总结如下。

javascript url解析

推荐的方法有: 方法1 ,方法5,方法6

  • 方法1: 该方法稳定。参数无需decodeURIComponent,同一个参数存在多个值的时候,不会存在覆盖
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', '中国' ] }
  • 方法2: 该方法摘选百度的js.
    缺点:不过这个代码并不优雅,当参数存在多个值的时候,就会导致参数覆盖。
    缺点:ds=1%202+3 解析为了ds: ‘1 2+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: '中国' }
  • 方法3 :使用json解析. 使用正则将格式转换为JSON,然后进行处理。该方法与方法2一样,存在两个缺点。
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) }));
  • 方法4:Object.fromEntries方法。这个方法存在相同参数覆盖的情况,在多值参数的场景下,不能使用。
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);
  • 方法5: nodejs 环境中可使用这个方法。该方法比较严谨。
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']
}
  • 方法6: 该方法也比较完美。值得推荐。
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);

python url 解析

直接使用默认的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', '中国']}

kotlin web中url参数解析

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)
}

java url 参数解析

  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)));
    }

kotlin url 参数解析

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)))
}

php url 相同参数值解析

$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;

golang url 参数解析

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站点有添加。

end
  • 作者:kali(作者介绍)
  • 更新时间:2022-07-20 18:09
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:转载站点文章,请附上原文链接
  • 翻译声明:翻译文章会不严谨,请务必附上原文链接
  • 扫描阅读:扫描二维码,手机阅读该文章