XMLHttpRequest读取xml乱码及请求封装

实现原生请求XMLHttpRequest对接本地控件接口返回xml出现乱码问题,找了很多方式解决,根据不同情况有不同的解决方式,稍微解释一下其他解决方式
在这里插入图片描述

  • 通常情况下修改请求头Content-type及修改编码格式可以解决。下面这种方式需要没有请求参数或者参数也是xml且返回类型为xml类型。
xmlHttp.setRequestHeader("Content-type", "application/xml;charset=utf-8");

常见的Content-type

Content-Type: text/plain; // 空白形式
Content-Type: text/html; // html形式
Content-Type: application/json; // json形式
Content-Type: application/x-www-form-urlencoded; // 表单形式
Content-Type: application/xml; // xml形式

  • 当返回内容responseText为乱码时,可以尝试获取responseXML。

以上两种方式需要后端配合解决,具体需要解决到哪一步,主要还是看后端怎么配置。下面的情况是没有后端配合且返回xml文件编码格式为gbk。

overrideMimeType解决

overrideMimeType用于指定需要的类型代替服务器返回的类型。由于我这里数据返回为xml,所以通过overrideMimeType指定application/xml类型。

// 在send前配置  指定的类型可以根据实际修改为需要的类型
xmlHttp.overrideMimeType("application/xml;charset=utf-8");

修改后若responseTex仍为乱码,可以尝试获取responseXML,通过节点方式获取值;或者打印整个请求对象找到复核条件的属性。我这里获取的是responseXML。

在这里插入图片描述

XMLHttpRequest封装

/**
 * httpRequest 封装请求
 * @param {Object} options 请求参数
 *    { string } url 请求地址
 *    { string } type 请求类型
 *    { string | object } params 请求参数
 *    { Object } headers 请求头
 *    { Function } setHttp 重写请求
 *    { string } isString 返回类型
 *    { string } ret 返回字段  text返回responseText, xml返回responseXML
 * @returns Promise
 */
function httpRequest(options) {
  const { headers = {}, params = {}, type = 'GET', ret = 'text' } = options;
  let { url = '', sendParams = '' } = options;
  const paramString = isString(params) ? params : changeParamsToString(params);
  if (type.toLowerCase() === 'get' && paramString.length > 0) {
    url = joinStringInUrl(url, paramString);
  }
  if (type.toLowerCase() === 'post') {
    sendParams = paramString || null;
  }
  return new Promise((resolve, reject) => {
    const xmlHttp = new XMLHttpRequest();
    xmlHttp.open(type, url, true);
    for (const item in headers) {
      xmlHttp.setRequestHeader(item, headers[item]);
    }

    // 外部修改xml请求
    options.setHttp ? options.setHttp(xmlHttp) : '';

    // 发送请求
    xmlHttp.send(sendParams);
    xmlHttp.onreadystatechange = function() {
      if (xmlHttp.readyState === 4) {
        if (xmlHttp.status === 200) {
          if (options.isString) {
            resolve(ret === 'text' ? xmlHttp.responseText : xmlHttp.responseXML);
          } else {
            resolve(JSON.parse(xmlHttp.responseText));
          }
        } else {
          reject('出错');
        }
      }
    };
  });
}

function isString(obj: any) {
  return Object.prototype.toString.call(obj) === "[object String]";
}

function changeParamsToString(params) {
  const paramArr = [];
  for (const item in params) {
    paramArr.push(item + '=' + params[item]);
  }
  return paramArr.length > 0 ? paramArr.join('&') || '' : '';
}

function joinStringInUrl(url, paramString) {
  return url.indexOf('?') === -1 ? (url + '?' + paramString) : (url + paramString);
}

// 调用方式
httpRequest({
   url: url,
   type: 'post',
   params: {
   		aa: 1,
   },
   headers: {
     "Content-type": "application/json;charset=utf-8",
   },
   isString: true,
   setHttp(xmlHttp) {
     xmlHttp.overrideMimeType("application/xml;charset=utf-8");
   },
 }).then(res => {
   console.log(res, 1111);
 });
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值