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