1 //调用方式: 2 ajax( 3 'http://www.baidu.com', 4 {name:'json'} 5 ).then((res)=>{ 6 console.log(res); 7 })
function ajax(url,data) { return new Promise((resolve,reject)=>{ let xhr = new XMLHttpRequest(); let temp = '?'; for(let key in data){ temp = temp + key + '=' + data[key] + '&'; } temp = temp.substr(0, temp.length - 1); xhr.open('get', url+temp); xhr.setRequestHeader("Content-type", 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { resolve(xhr.responseText); } } xhr.send(temp); }); }
其中:
1 //(如果需要设置特殊的表单提交方式)则修改(post、get都可以) 2 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 3 //application/x-www-form-urlencoded -> 4 let data = "name=json"; 5 6 //application/json -> (只能通过post方式请求) 7 let data = JSON.stringify({name:'json'}); 8 9 //multipart/form-data ->
10 let data = new FormData();
11 data.append('name','json');
get请求的数据放到url中拼接,post请求的数据放到 xhr.send(temp); 里面,get请求的数据放到xhr.send(temp);里面会被忽略!!!
或者你也可以简单一点直接使用axios:
npm install axios import axios from 'axios' Vue.prototype.$axios = axios; this.$axios.post('http://localhost:9000/api/user/login',{ name:'test' , password:'123456' }).then(res=>{ console.log(res) })
拦截请求:
function proxyRequest() { const _request_ = window.XMLHttpRequest; const obj = new _request_(); const submit = obj.open; let interceptors = [] obj.open = function () { for (let i = 0; i < interceptors.length; i++) { const item = interceptors[i] if(arguments[1].indexOf(item.url) > -1){ console.log('start intercept request:',item) Object.defineProperty(obj,'responseText',{ set(){}, get(){return item.responseText} }) Object.defineProperty(obj,'response',{ set(){}, get(){return item.responseText} }) break; } } return submit.apply(this,arguments) } window.XMLHttpRequest = function () { return obj; }; return { set(val){ interceptors = val }, get(){ return interceptors } } } //let handler = proxyRequest() // handler.get() // handler.set([{url:'api',responseText:'hhh'}])
添加数据模拟、转换器:
var api = { xhr: new XMLHttpRequest(), _requestParam: "", request: function (url, data) { _requestParam = "?"; for (var key in data) _requestParam = _requestParam + key + "=" + data[key] + "&"; _requestParam = _requestParam.substr(0, _requestParam.length - 1); this.xhr.open("get", url + _requestParam); this.xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); return this; }, _mock: false, _mockData: {}, _mockTime: 0, _debug: false, mock: function (data, time, debug) { this._mock = true; this._mockData = data; this._mockTime = time; this._debug = debug; return this; }, _converter: function (e) { return e; }, converter: function (e) { this._converter = e; return this; }, get: function (cb) { if (this._mock) { setTimeout( function () { if (this._debug) debugger; cb(this._converter(this._mockData)); this.clean(); }.bind(this), this._mockTime ); } else { this.xhr.onreadystatechange = function () { if (this.xhr.readyState == 4 && this.xhr.status == 200) { cb(xhr.responseText); this.clean(); } }; this.xhr.send(this._requestParam); } }, clean: function () { this._mock = false; this._requestParam = ""; this._mockData = {}; }, };
api .request("userInfo") // 发送请求 .mock( // 模拟后端返回数据 [ { coin: 2, score: 2, username: 456456, }, { coin: 2, score: 2, username: 456456, }, ], 1000, // 模拟请求延迟事件 false // 开启调试功能 ) .converter(function (e) { // 数据转换 return e[0]; }) .get((res) => { // 获取返回数据 console.log(res); });
升级上面的程序:
var api = myFetch("http://www.baidu.com"); function myFetch(baseUrl, handler) { var xhr = new XMLHttpRequest(); var _mock = false; var _mockData = {}; var _mockTime = 0; var _debug = false; var _converter = function (e) { return e; }; var _requestParam = ""; var _preHandler = function (e) { return e; }; var _postHandler = function (e) { return e; }; var clean = function () { _mock = false; _requestParam = ""; _mockData = {}; _converter = function (e) { return e; }; _preHandler = function (e) { return e; }; _postHandler = function (e) { return e; }; }; var Api = { request: function (url, data) { _requestParam = "?"; for (var key in data) _requestParam = _requestParam + key + "=" + data[key] + "&"; _requestParam = _requestParam.substr(0, _requestParam.length - 1); xhr.open("get", baseUrl + url + _requestParam); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); if (handler) { handler.preHandler && (_preHandler = handler.preHandler); handler.postHandler && (_postHandler = handler.postHandler); } return this; }, mock: function (data, time, debug) { _mock = true; _mockData = { success: true, data, code: 200, }; _mockTime = time || 0; _debug = debug; return this; }, preHandler(cb) { _preHandler = cb; return this; }, postHandler(cb) { _postHandler = cb; return this; }, converter: function (e) { _converter = e; return this; }, get: function (cb) { if (_mock) { setTimeout( function () { if (_debug) debugger; cb(_converter(_postHandler(_mockData))); clean(); }.bind(this), _mockTime ); } else { xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { cb(_converter(_postHandler(xhr.responseText))); clean(); } }; xhr.send(_requestParam); } }, }; return Api; }
升级 添加多线程访问:
/* var test = api("baseUrl",...); test.request("/mock",{...}).mock({...}).converter(e=>e).get(function(e){ ...e }) */ var api = myFetch("http://localhost:80/API"); function myFetch(baseUrl, handler) { var obj = null; var DataSource = function () { return { xhr: new XMLHttpRequest(), _mock: false, _mockData: {}, _mockTime: 0, _debug: false, _requestParam: "", _converter: function (e) { return e; }, _preHandler: function (e) { return e; }, _postHandler: function (e) { return e; }, }; }; var Api = { url: function (param) { return baseUrl + (param ? param : ""); }, post: function (url, data) { obj = new DataSource(); obj._requestParam = "?"; for (var key in data) obj._requestParam = obj._requestParam + key + "=" + data[key] + "&"; obj._requestParam = obj._requestParam.substr( 0, obj._requestParam.length - 1 ); obj.xhr.open("post", baseUrl + url + obj._requestParam); obj.xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); if (handler) { handler.preHandler && (obj._preHandler = handler.preHandler); handler.postHandler && (obj._postHandler = handler.postHandler); } return this; }, request: function (url, data) { obj = new DataSource(); obj._requestParam = "?"; for (var key in data) obj._requestParam = obj._requestParam + key + "=" + data[key] + "&"; obj._requestParam = obj._requestParam.substr( 0, obj._requestParam.length - 1 ); obj.xhr.open("get", baseUrl + url + obj._requestParam); obj.xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); if (handler) { handler.preHandler && (_preHandler = handler.preHandler); handler.postHandler && (_postHandler = handler.postHandler); } return this; }, mock: function (data, time, debug) { obj._mock = true; obj._mockData = { success: true, data, code: 200, }; obj._mockTime = time || 0; obj._debug = debug; return this; }, preHandler(cb) { obj._preHandler = cb; return this; }, postHandler(cb) { obj._postHandler = cb; return this; }, converter: function (e) { obj._converter = e; return this; }, getJson: function (cb) { this.get(function (data) { cb(JSON.parse(data)); }); }, get: function (cb) { if (obj._mock) { setTimeout( function () { if (obj._debug) debugger; cb(obj._converter(obj._postHandler(obj._mockData))); // clean(); }.bind(this), obj._mockTime ); } else { obj.xhr.onreadystatechange = function () { if (this.xhr.readyState == 4 && this.xhr.status == 200) { cb(this._converter(this._postHandler(this.xhr.responseText))); // clean(); } }.bind(obj); obj.xhr.send(obj._requestParam.substring(1)); } }, }; return Api; }
升级ts:
//api
declare type pureStrObj = { [key: string]: string };
declare type postDataType = { [any: string]: any } | FormData | undefined;
declare type setCredentialFooType = (this: apiType, token: string) => void;
declare interface apiType {
_branch: string;
_headers: pureStrObj;
url: (param: string) => string;
removeCredential: () => apiType;
withCredential: (
token?: string
// setCredential?: (credentail: object) => void
) => apiType;
setCredentialFoo: (foo: setCredentialFooType) => void;
setHeaders: (headers: pureStrObj) => apiType;
setBranch: (branch: string) => apiType;
post: (url: string, data?: postDataType) => apiType;
request: (
url: string,
data?: {
[any: string]: any;
}
) => apiType;
mock: (data: any, time?: number, debug?: boolean) => apiType;
preHandler: (cb: (e: any) => any) => apiType;
postHandler: (cb: (e: any) => any) => apiType;
converter: (e: (e: any) => any) => apiType;
getJson: (cb: (e: any) => any) => void;
get: (cb: (e: any) => any) => void;
}
declare const api: apiType;
//api
interface apiSource { xhr: XMLHttpRequest; type: "get" | "post"; url: string; //完整请求地址 headers: pureStrObj; _branch: string; //请求分支 _mock: boolean; //模拟请求 _mockData: {}; //模拟数据 _mockTime: number; //模拟响应延迟 _debug: boolean; // 是否debug _requestParam: string | FormData; //请求参数 _converter: (e: any) => any; //转换器 _preHandler: (e: any) => any; //前置处理器 _postHandler: (e: any) => any; //后置处理器 } const api = myFetch("http://127.0.0.1:80", "/API"); interface handlerType { preHandler?: () => void; postHandler?: () => void; } // interface apiType { // _branch: string; // _headers: pureStrObj; // url: (param: string) => string; // removeCredential: () => apiType; // withCredential: ( // token?: string // // setCredential?: (credentail: object) => void // ) => apiType; // setCredentialFoo: (foo: setCredentialFooType) => void; // setHeaders: (headers: pureStrObj) => apiType; // setBranch: (branch: string) => apiType; // post: (url: string, data?: postDataType) => apiType; // request: ( // url: string, // data: { // [any: string]: any; // } // ) => apiType; // mock: (data: any, time?: number, debug?: boolean) => apiType; // preHandler: (cb: (e: any) => any) => apiType; // postHandler: (cb: (e: any) => any) => apiType; // converter: (e: (e: any) => any) => apiType; // getJson: (cb: (e: any) => any) => void; // get: (cb: (e: any) => any) => void; // } function myFetch(baseUrl: string, branch: string, handler?: handlerType) { var obj: null | apiSource = null; class DataSource implements apiSource { xhr = new XMLHttpRequest(); type: "post" | "get" = "post"; url = ""; headers = { "Content-type": "application/x-www-form-urlencoded", }; _branch = ""; _mock = false; _mockData = {}; _mockTime = 0; _debug = false; _requestParam = ""; _converter = function (e: any) { return e; }; _preHandler = function (e: any) { return e; }; _postHandler = function (e: any) { return e; }; constructor() {} } const analysisParam = function ( obj: apiSource, url: string, data: postDataType, dataType: string ) { obj.url = obj.url === "" ? baseUrl + obj._branch + url : obj.url; if (data) { switch (obj.headers["Content-type"]) { case "application/x-www-form-urlencoded": obj._requestParam = obj.url.indexOf("?") > -1 ? "&" : "?"; // if (dataType !== "[object object]") { // throw Error("request header does not match request data!"); // } if (data instanceof FormData) return; for (let key in data) obj._requestParam = obj._requestParam + key + "=" + data[key] + "&"; obj._requestParam = obj._requestParam.substr( 0, obj._requestParam.length - 1 ); break; case "multipart/form-data": // if (dataType !== "[object FormData]") { // throw Error("request header does not match request data!"); // } obj._requestParam = data as FormData; break; case "application/json": // if (dataType !== "[object object]") { // throw Error("request header does not match request data!"); // } obj._requestParam = JSON.stringify(data); break; } } obj.xhr.open(obj.type, obj.url); }; const setHeadersHandler = ( obj: apiSource, headers: { [any: string]: string }, dataType: string ) => { if (obj._mock) return; switch (dataType) { case "[object FormData]": obj.xhr.setRequestHeader("Content-type", "multipart/form-data"); break; case "[object object]": obj.xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); break; } for (const key in obj.headers) { obj.xhr.setRequestHeader(key, obj.headers[key]); } for (const key in headers) { obj.xhr.setRequestHeader(key, headers[key]); } }; const setHandlers = (handler: handlerType, obj: apiSource) => { handler.preHandler && (obj._preHandler = handler.preHandler); handler.postHandler && (obj._postHandler = handler.postHandler); }; const responseTextParser = function ( // this: apiSource, obj: apiSource, cb: (data: any) => void ) { if (obj._mock) { const obj2 = obj; setTimeout( function () { if (obj2._debug) debugger; cb(obj2._converter(obj2._postHandler(obj2._mockData))); }.bind(obj), obj._mockTime ); } else { obj.xhr.onreadystatechange = function (this: apiSource) { if (this.xhr.readyState == 4 && this.xhr.status == 200) { cb(this._converter(this._postHandler(this.xhr.responseText))); } }.bind(obj); obj.xhr.send( obj.headers["Content-type"] === "multipart/form-data" ? obj._requestParam : "" ); } }; let _credentialFoo: setCredentialFooType = function ( this: apiType, token: string ) { this.setHeaders({ token }); }; var Api: apiType = { _branch: branch, _headers: {}, url: (param: string) => { return baseUrl + (param ? param : ""); }, setCredentialFoo(foo) { _credentialFoo = foo; }, removeCredential() { localStorage.removeItem("credentail"); return this; }, withCredential(token) { let credential; if (token) { localStorage.setItem("credentail", token); credential = token; } else { credential = localStorage.getItem("credential") || ""; } _credentialFoo.call(this, credential); return this; }, setHeaders: function (headers: { [any: string]: string }) { for (const key in headers) { this._headers[key] = headers[key]; } return this; }, setBranch: function (branch: string) { this._branch = branch; return this; }, post: function (url: string, data?: postDataType) { obj = new DataSource(); obj._branch = this._branch; const dataType = Object.prototype.toString.call(data); analysisParam(obj, url, data, dataType); setHeadersHandler(obj, this._headers, dataType); handler && setHandlers(handler, obj); return this; }, request: function ( url: string, data?: { [any: string]: any; } ) { obj = new DataSource(); obj.type = "get"; obj._branch = this._branch; const dataType = Object.prototype.toString.call(data); analysisParam(obj, url, data, dataType); setHeadersHandler(obj, this._headers, dataType); handler && setHandlers(handler, obj); return this; }, mock: function (data: any, time?: number, debug?: boolean) { if (obj === null) { console.log("please send request first"); return this; } obj._mock = true; obj._mockData = { success: true, data, code: 200, }; obj._mockTime = time || 0; obj._debug = debug || false; return this; }, preHandler(cb: (e: any) => any) { if (obj === null) { console.log("please send request first"); return this; } obj._preHandler = cb; return this; }, postHandler(cb: (e: any) => any) { if (obj === null) { console.log("please send request first"); return this; } obj._postHandler = cb; return this; }, converter: function (e: (e: any) => any) { if (obj === null) { console.log("please send request first"); return this; } obj._converter = e; return this; }, getJson: function (cb: (e: any) => any) { if (obj === null) { console.log("please send request first"); return this; } responseTextParser(obj, (data) => { cb(JSON.parse(data)); }); }, get: function (cb: (e: any) => any) { if (obj === null) { console.log("please send request first"); return this; } responseTextParser(obj, cb); }, }; return Api; }