实现原生请求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);
});