【js】URL处理

发布于:2025-02-11 ⋅ 阅读:(106) ⋅ 点赞:(0)

背景

有这样子一个url,search部分的value可能包含空格,也可能是一个对象,如何正确解析这样子的url呢?

search如下,?accountId=144115188076933939&accountName=mock name&xxx

{
    "accountId": "144115188076933939",
    "accountName": "mock name", // 空格
    "accountNumber": "*1623",
    "accountType": "6",
    "bankId": "36",
    "bankName": "DUIT NOW OB PHONE NUMBER",
    "proxyType": "1",
    "recipientType": "3",
    "saved": "true",
    "status": "2",
    "test": { // json对象
        "1": 1,
        "2": 2
    }
}

空格

通常来说,空格在URL中通常需要被编码为%20或者+。有这样子的两个方法,encodeURIComponent和decodeURIComponent对url进行编码和解码操作。

encodeURIComponent('?accountId=144115188076933939&accountName=mock name')

// 输出
?accountId=144115188076933939&accountName=mock%20name

json对象

编码的时候,将对象序列化成字符串,然后再调用encodeURIComponent;
解码的时候,就先parse成对象,再调用decodeURIComponent。

代码

遍历json对象,如果value为对象的话,则将其stringify成字符串:

export function shallowStringifyObjectFields(
  obj: Record<
    string,
    string | number | boolean | Record<string, unknown> | null | undefined
  >
): Record<string, string | number | boolean | null | undefined> {
  const newObj: Record<
    string,
    string | number | boolean | null | undefined
  > = {};
  for (const key of Object.keys(obj)) {
    const val = obj[key];
    if (typeof val === 'object' && val) {
      newObj[key] = JSON.stringify(val);
    } else {
      newObj[key] = val;
    }
  }
  return newObj;
}

将对象转换成url search,类似?xx=xx这样子的字符串:

/**
 * format a javascript object into query string, keep the key value in alphabetic order
 * @static
 * @param {object} json
 * @returns {string} query string
 */
export function jsonToQueryString(
  json: Record<
    string,
    string | null | undefined | number | boolean | Array<any>
  >,
  skipQuestionMark = false
): string {
  if (!json) {
    return '';
  }
  const keys = Object.keys(json).filter(key => {
    const val = json[key];
    return typeof val !== 'undefined' && val !== null;
  });
  if (!keys.length) {
    return '';
  }
  return (
    (skipQuestionMark ? '' : '?') +
    keys
      .sort()
      .map(function (key) {
        return (
          encodeURIComponent(key) +
          '=' +
          // undefined | null is already filtered out above
          encodeURIComponent(json[key] as string | number | boolean)
        );
      })
      .join('&')
  );
}

将url search字符串解析成对象:

/**
 * Parse query string using string splitting
 * @static
 * @param {string} queryString
 * @return {Object.<string>}
 */
export function parseQueryStringToObj(
  queryString: string | null | undefined
): {
  [key: string]: string;
} {
  const dictionary: {
    [key: string]: string;
  } = {};

  if (typeof queryString !== 'string' || queryString.length === 0) {
    return dictionary;
  }

  // remove the '?' from the beginning of the
  // if it exists
  if (queryString.indexOf('?') === 0) {
    queryString = queryString.substr(1);
  }
  if (!queryString.length) {
    return dictionary;
  }

  // Step 1: separate out each key/value pair
  const parts = queryString.split('&');

  for (let i = 0; i < parts.length; i++) {
    const p = parts[i];
    // Step 2: Split Key/Value pair
    const keyValuePair = p.split('=');

    // Step 3: Add Key/Value pair to Dictionary object
    const key = keyValuePair[0];
    let value = keyValuePair[1];

    // decode URI encoded string
    value && value.replace(/\+/g, '%20');
    value = decodeURIComponent(value); // 解码

    dictionary[key] = value;
  }

  // Step 4: Return Dictionary Object
  return dictionary;
}