URLEncoder和URLDecoder

一、初步了解

先看代码

public class URLEncodeTest {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //将application/x-www-form-urlencoded字符串转换成普通字符串
        String keyWord = URLDecoder.decode("%E5%BC%80%E5%8F%91%E6%B5%8B%E8%AF%95_test44444", "UTF-8");
        System.out.println(keyWord);
        //将普通字符串转换成application/x-www-form-urlencoded字符串 开发测试_test44444
        String urlStr = URLEncoder.encode("开发测试_test44444" , "UTF-8");
        System.out.println(urlStr);
    }
}

结果如下:

开发测试_test44444
%E5%BC%80%E5%8F%91%E6%B5%8B%E8%AF%95_test44444

URLDecoder类包含一个decode(String s,String charcter)静态方法,它可以将看上去乱码的特殊字符串转换成普通字符串。

URLEncoder类包含一个encode(String s,String charcter)静态方法,它可以将普通字符串转换成application/x-www-form-urlencoded MIME字符串。

二、文件下载时文件名为什么要用URLEncoder编码

如果不使用URLEncoder进行编码,代码如下:

//        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setHeader("content-disposition", "attachment;filename=" + fileName);

效果如下:

content-disposition: attachment;filename=????_test44444.txt

原因分析:当URL地址中仅包含普通非中文字符串和application/x-www-form-urlencoded MIME字符串无须转换,而包含中文字符串的普通字符串则需要转换,换句话说,也就是说URL地址中有"中文字符串"传递时,才会考虑用到上面提到的两个类,这样就可以将传递过来的中文接受后,再还原成原来的中文字符串.如不转换,则通过URL传递过来的中文字符中会变成乱码,无法还原了。同样,响应头中存在中文字符串时也一样。

所以,在后端用URLEncoder编码,然后在前端解码

后端编码

response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

前端解码

//从响应头获取文件名
export function getFileNameFromHeader(response) {
  const disposition = response.headers["content-disposition"]
  let fileName = disposition.substring(disposition.indexOf("filename=") + 9);
  if (window.navigator.userAgent.indexOf("Firefox") > -1) {
    fileName = fileName.substring(fileName.indexOf("-8?B?") + 5, fileName.indexOf("?="))
    fileName = base64Util.decode(fileName);
  } else {
    fileName = decodeURIComponent(fileName);
  }
  return fileName
}

前端进行编码和解码的方法:

/**
 * Gets the unencoded version of an encoded component of a Uniform Resource Identifier (URI).
 * @param encodedURIComponent A value representing an encoded URI component.
 */
declare function decodeURIComponent(encodedURIComponent: string): string;
/**
 * Encodes a text string as a valid component of a Uniform Resource Identifier (URI).
 * @param uriComponent A value representing an encoded URI component.
 */
declare function encodeURIComponent(uriComponent: string | number | boolean): string;

三、应用场景

1、所有的GET请求

2、网址中有中文等情况

3、POST请求,所有的Key和Value在提交之前都要经过URLEncoder

例子:请求拦截器中对请求体的value进行编码,然后再拼接到url中。

service.interceptors.request.use(

  config => {
    if (store.getters.token) {
      config.headers['Authorization'] = store.getters.token
    }

    // params参数编码
    let url = config.url;
    if (config.params) {
      url += '?';
      let keys = Object.keys(config.params);
      for (let key of keys) {
        if (config.params[key] !== null && config.params[key] !== "") {
          url += `${key}=${encodeURIComponent(config.params[key])}&`;
        }
      }
      url = url.substring(0, url.length - 1);
      config.params = {};
    }
    config.url = url;
    return config;
  },
  error => {
    console.log(error) // for debug
    Promise.reject(error)
  }
)

 

上一篇:接口返回图片,前端生成临时url实现展示、下载效果


下一篇:使用cat-EOF时的一些坑