/**
* ========================http========================
*/
var httpUtil = {
/**
* XMLHttpRequest是一個瀏覽器接口,使得Javascript可以進行HTTP(S)通信,這就是我們熟悉的AJAX。
* xhr.readyState:XMLHttpRequest對象的狀態,等於4表示數據已經接收完畢。
* xhr.status:服務器返回的狀態碼,等於200表示一切正常。
* xhr.responseText:服務器返回的文本數據
* xhr.responseXML:服務器返回的XML格式的數據
* xhr.statusText:服務器返回的狀態文本。
* @returns {boolean}
* @constructor
*/
"XMLHttpRequest": function(){
var xhr = null;
if(window.XMLHttpRequest){ //非IE瀏覽器&IE6+
xhr = new XMLHttpRequest();
}else if(window.ActiveXObject){ //IE瀏覽器:IE5&IE6
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}else{
alert("Your browser does not support XMLHTTP.");
return false;
}
var fileurl = "/..."; //資源請求路徑(包含js文件內聯實現,或者接口路徑等)
xhr.open("GET",fileurl,true); //第三個參數爲async是否爲異步,默認爲true
//監聽請求完成事件
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 ){ //四個狀態: 1.uninitialized 未初始化 2.loading 加載中 3.loaded 加載完成 4.complete 完成
if(xhr.status>=200&&xhr.status<300 || xhr.status==304){ //200<=狀態碼<300爲有效請求,304爲緩存中獲取
var responsetext = xhr.responseText; //服務器返回的文本數據
}else{
alert(xhr.statusText); //服務器返回的狀態文本
}
}
};
var formData = new FormData();
formData.append('tel', '18217767969');
formData.append('psw', '111111');
xhr.send(formData); //發送請求內容,沒內容時,傳值爲null
}
}
/**
* http.js start
* @type {{request: http.request, addAuthorizationHeader: http.addAuthorizationHeader, post: http.post, postBody: http.postBody, get: http.get, getQueryString: (function(*=): string), ajax: http.ajax, delete: http.delete, getUrlParam: http.getUrlParam, getQueryData: http.getQueryData}}
*/
const http = {
/**
* js封裝ajax請求
* >>使用new XMLHttpRequest 創建請求對象,所以不考慮低端IE瀏覽器(IE6及以下不支持XMLHttpRequest)
* >>使用es6語法,如果需要在正式環境使用,則可以用babel轉換爲es5語法 https://babeljs.cn/docs/setup/#installation
*
* @param settings 請求參數模仿jQuery ajax
* 調用該方法,data參數需要和請求頭Content-Type對應
* Content-Type data 描述
* application/x-www-form-urlencoded 'name=哈哈&age=12'或{name:'哈哈',age:12} 查詢字符串,用&分割
* application/json name=哈哈&age=12' json字符串
* multipart/form-data new FormData() FormData對象,當爲FormData類型,不要手動設置Content-Type
* 注意:請求參數如果包含日期類型.是否能請求成功需要後臺接口配合
*/
"ajax": (settings = {}) => {
// 初始化請求參數
let _s = Object.assign({
url: '', // string
type: 'GET', // string 'GET' 'POST' 'DELETE'
dataType: 'json', // string 期望的返回數據類型:'json' 'text' 'document' ...
async: true, // boolean true:異步請求 false:同步請求 required
data: null, // any 請求參數,data需要和請求頭Content-Type對應
headers: {}, // object 請求頭
timeout: 1000, // string 超時時間:0表示不設置超時
beforeSend: (xhr) => {
},
success: (result, status, xhr) => {
},
error: (xhr, status, error) => {
},
complete: (xhr, status) => {
}
}, settings);
// 參數驗證
if (!_s.url || !_s.type || !_s.dataType || !_s.async) {
alert('參數有誤');
return;
}
// 創建XMLHttpRequest請求對象
let xhr = new XMLHttpRequest();
// 請求開始回調函數
xhr.addEventListener('loadstart', e => {
_s.beforeSend(xhr);
});
// 請求成功回調函數
xhr.addEventListener('load', e => {
const status = xhr.status;
if ((status >= 200 && status < 300) || status === 304) {
let result;
if (xhr.responseType === 'text') {
result = xhr.responseText;
} else if (xhr.responseType === 'document') {
result = xhr.responseXML;
} else {
result = xhr.response;
}
// 注意:狀態碼200表示請求發送/接受成功,不表示業務處理成功
_s.success(result, status, xhr);
} else {
_s.error(xhr, status, e);
}
});
// 請求結束
xhr.addEventListener('loadend', e => {
_s.complete(xhr, xhr.status);
});
// 請求出錯
xhr.addEventListener('error', e => {
_s.error(xhr, xhr.status, e);
});
// 請求超時
xhr.addEventListener('timeout', e => {
_s.error(xhr, 408, e);
});
let useUrlParam = false;
let sType = _s.type.toUpperCase();
// 如果是"簡單"請求,則把data參數組裝在url上
if (sType === 'GET' || sType === 'DELETE') {
useUrlParam = true;
_s.url += http.getUrlParam(_s.url, _s.data);
}
// 初始化請求
xhr.open(_s.type, _s.url, _s.async);
// 設置期望的返回數據類型
xhr.responseType = _s.dataType;
// 設置請求頭
for (const key of Object.keys(_s.headers)) {
xhr.setRequestHeader(key, _s.headers[key]);
}
// 設置超時時間
if (_s.async && _s.timeout) {
xhr.timeout = _s.timeout;
}
// 發送請求.如果是簡單請求,請求參數應爲null.否則,請求參數類型需要和請求頭Content-Type對應
xhr.send(useUrlParam ? null : http.getQueryData(_s.data));
},
// 把參數data轉爲url查詢參數
"getUrlParam": (url, data) => {
if (!data) {
return '';
}
let paramsStr = data instanceof Object ? http.getQueryString(data) : data;
return (url.indexOf('?') !== -1) ? paramsStr : '?' + paramsStr;
},
// 獲取ajax請求參數
"getQueryData": (data) => {
if (!data) {
return null;
}
if (typeof data === 'string') {
return data;
}
if (data instanceof FormData) {
return data;
}
return http.getQueryString(data);
},
// 把對象轉爲查詢字符串
"getQueryString": (data) => {
let paramsArr = [];
if (data instanceof Object) {
Object.keys(data).forEach(key => {
let val = data[key];
// todo 參數Date類型需要根據後臺api酌情處理
if (val instanceof Date) {
val = dateFormat(val, 'yyyy-MM-dd hh:mm:ss');
}
paramsArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(val));
});
}
return paramsArr.join('&');
},
/**
* 根據實際業務情況裝飾 ajax 方法
* 如:統一異常處理,添加http請求頭,請求展示loading等
* @param settings
*/
"request": (settings = {}) => {
// 統一異常處理函數
let errorHandle = (xhr, status) => {
console.log('request error...');
if (status === 401) {
console.log('request 沒有權限...');
}
if (status === 408) {
console.log('request timeout');
}
};
// 使用before攔截參數的 beforeSend 回調函數
settings.beforeSend = (settings.beforeSend || function () {
}).before(xhr => {
console.log('request show loading...');
});
// 保存參數success回調函數
let successFn = settings.success;
// 覆蓋參數success回調函數
settings.success = (result, status, xhr) => {
// todo 根據後臺接口api判斷是否請求成功
if (result && result instanceof Object && result.code !== 1) {
errorHandle(xhr, status);
} else {
console.log('request success');
successFn && successFn(result, status, xhr);
}
};
// 攔截參數的 error
settings.error = (settings.error || function () {
}).before((result, status, xhr) => {
errorHandle(xhr, status);
});
// 攔截參數的 complete
settings.complete = (settings.complete || function () {
}).after((xhr, status) => {
console.log('request hide loading...');
});
// 請求添加權限頭,然後調用http.ajax方法
(http.ajax.before(http.addAuthorizationHeader))(settings);
},
// 添加權限請求頭
"addAuthorizationHeader": (settings) => {
settings.headers = settings.headers || {};
const headerKey = 'Authorization'; // todo 權限頭名稱
// 判斷是否已經存在權限header
let hasAuthorization = Object.keys(settings.headers).some(key => {
return key === headerKey;
});
if (!hasAuthorization) {
settings.headers[headerKey] = 'test'; // todo 從緩存中獲取headerKey的值
}
},
"get": (url, data, successCallback, dataType = 'json') => {
http.request({
url: url,
type: 'GET',
dataType: dataType,
data: data,
success: successCallback
});
},
"delete": (url, data, successCallback, dataType = 'json') => {
http.request({
url: url,
type: 'DELETE',
dataType: dataType,
data: data,
success: successCallback
});
},
// 調用此方法,參數data應爲查詢字符串或普通對象
"post": (url, data, successCallback, dataType = 'json') => {
http.request({
url: url,
type: 'POST',
dataType: dataType,
data: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
success: successCallback
});
},
// 調用此方法,參數data應爲json字符串
"postBody": (url, data, successCallback, dataType = 'json') => {
http.request({
url: url,
type: 'POST',
dataType: dataType,
data: data,
headers: {
'Content-Type': 'application/json; charset=UTF-8'
},
success: successCallback
});
}
};
Function.prototype.before = function (beforeFn) { // eslint-disable-line
let _self = this;
return function () {
beforeFn.apply(this, arguments);
_self.apply(this, arguments);
};
};
Function.prototype.after = function (afterFn) { // eslint-disable-line
let _self = this;
return function () {
_self.apply(this, arguments);
afterFn.apply(this, arguments);
};
};
// 日期格式化
const dateFormat = (date, sFormat = 'yyyy-MM-dd') => {
if (!(date instanceof Date)) {
return;
}
let time = {
Year: 0,
TYear: '0',
Month: 0,
TMonth: '0',
Day: 0,
TDay: '0',
Hour: 0,
THour: '0',
hour: 0,
Thour: '0',
Minute: 0,
TMinute: '0',
Second: 0,
TSecond: '0',
Millisecond: 0
};
time.Year = date.getFullYear();
time.TYear = String(time.Year).substr(2);
time.Month = date.getMonth() + 1;
time.TMonth = time.Month < 10 ? '0' + time.Month : String(time.Month);
time.Day = date.getDate();
time.TDay = time.Day < 10 ? '0' + time.Day : String(time.Day);
time.Hour = date.getHours();
time.THour = time.Hour < 10 ? '0' + time.Hour : String(time.Hour);
time.hour = time.Hour < 13 ? time.Hour : time.Hour - 12;
time.Thour = time.hour < 10 ? '0' + time.hour : String(time.hour);
time.Minute = date.getMinutes();
time.TMinute = time.Minute < 10 ? '0' + time.Minute : String(time.Minute);
time.Second = date.getSeconds();
time.TSecond = time.Second < 10 ? '0' + time.Second : String(time.Second);
time.Millisecond = date.getMilliseconds();
return sFormat.replace(/yyyy/ig, String(time.Year))
.replace(/yyy/ig, String(time.Year))
.replace(/yy/ig, time.TYear)
.replace(/y/ig, time.TYear)
.replace(/MM/g, time.TMonth)
.replace(/M/g, String(time.Month))
.replace(/dd/ig, time.TDay)
.replace(/d/ig, String(time.Day))
.replace(/HH/g, time.THour)
.replace(/H/g, String(time.Hour))
.replace(/hh/g, time.Thour)
.replace(/h/g, String(time.hour))
.replace(/mm/g, time.TMinute)
.replace(/m/g, String(time.Minute))
.replace(/ss/ig, time.TSecond)
.replace(/s/ig, String(time.Second))
.replace(/fff/ig, String(time.Millisecond));
};
/**
* http.js end
*/
/**
* 調用頁面代碼 s
*/
/*
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="buttons">
<button id="get">get</button>
<button id="get_dataParam">get_dataParam</button>
<button id="get_timeout">get_timeout</button>
<button id="get_document">get_document</button>
<button id="get_exception">get_exception</button>
<button id="post_dataParam">post_dataParam</button>
<button id="post_formDataParam">post_formDataParam</button>
<button id="post_body">post_body</button>
<button id="post_body_list">post_body_list</button>
</div>
<br>
<div>
<label for="file">選擇文件,可多選:</label>
<input id="file" type="file" multiple>
<button id="upload">upload</button>
</div>
<br>
<div>
<label for="file">文件分塊傳輸:</label>
<input id="bidFile" type="file">
<button id="uploadFile">uploadFile</button>
</div>
<script src="http.js"></script>
<script>
document.getElementById('buttons').addEventListener('click', function (e) {
let url = 'http://88.128.18.144:8081/api/v1/test/';
const id = e.target.id;
if (id === 'get') {
url = url + id;
fetch(url + '?name=哈哈&age=12').then(res => res.json()).then(data => {
console.log(data);
});
}
if (id === 'get_dataParam') {
http.request({
url: url + id,
data: {name: '哈哈', age: 12}, //data: 'name=哈哈&age=12',
success: function (result, status, xhr) {
console.log(result, '\n status:', status, xhr);
debugger;
}
});
}
if (id === 'get_timeout') {
http.request({
url: url + id,
timeout: 1000
});
}
if (id === 'get_document') {
// http.request是針對這個api(http://88.128.18.144:8081/api/)封裝的,這裏請求另外一個接口,不能使用http.request
http.ajax({
url: 'http://172.16.19.136:9000/kit_file_server/',
dataType: 'document',
success: function (result, status, xhr) {
console.log(result, '\n status:', status, xhr);
debugger;
}
});
}
if (id === 'get_exception') {
http.get(url + id);
}
if (id === 'post_dataParam') {
url = url + id;
http.post(url, {name: '哈哈', age: 12}, (result, status, xhr) => {
console.log('進行業務操作');
})
}
if (id === 'post_formDataParam') {
// 傳FormData類型參數,不要設置contentType,瀏覽器會自動設置contentType爲'multipart/form-data'
let formData = new FormData();
formData.append('name', '哈哈');
formData.append('age', '123');
http.request({
url: url + id,
type: 'POST',
data: formData,
success: function (result, status, xhr) {
console.log('進行業務操作');
}
});
}
if (id === 'post_body') {
url = url + id;
http.postBody(url, JSON.stringify({
name: '哈哈',
age: 12,
birthday: dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss'),
hobbies: ['a', 'b', 'c']
}), (result, status, xhr) => {
console.log('進行業務操作');
});
}
if (id === 'post_body_list') {
url = url + id;
http.postBody(url, JSON.stringify(['a', 'b', 'c']), (result, status, xhr) => {
console.log('進行業務操作');
});
}
});
document.getElementById('upload').addEventListener('click', function () {
let files = document.getElementById('file').files;
if (files.length === 0) {
console.log('沒有選擇文件');
return;
}
let form = new FormData(); // FormData 對象
Array.from(files).forEach((file, index) => {
form.append(index, file); // 文件對象
});
http.ajax({
url: 'http://88.128.18.144:3333/upload?directory=test',
type: 'POST',
data: form,
success: function (result, status, xhr) {
console.log('文件上傳成功', result.data);
}
});
});
const LENGTH = 1024 * 100; // 100kb
document.getElementById('uploadFile').addEventListener('click', function () {
let file = document.getElementById('bidFile').files[0];
if (!file) {
console.log('沒有選擇文件');
return;
}
let start = 0, end = LENGTH;
while (start < file.size) {
let blob = file.slice(start, end);
let form = new FormData();
form.append('blob', blob);
http.ajax({
url: 'http://88.128.18.144:3333/upload?directory=test',
type: 'POST',
data: form,
success: function (result, status, xhr) {
console.log('文件分塊上傳', result.data);
}
});
start = end;
end = start + LENGTH;
}
});
</script>
</body>
</html>
*/
/**
* 調用頁面代碼 e
*/