浏览地址http://118.25.217.253:4000 账号test密码123 qq讨论群:836719189
要写这个系统,就需要数据来源,让我们先来看看如果通过客户端调用服务端api拿到数据
http访问服务端api我直接使用了XMLHttpRequest,并没用使用其它第三方组件。
用户通过登录界面登录获得token,把token写入到cookie,后面的api调用从cookie取出token写入到httpheader,这样登录后的每次请求都是带token的,都是安全调用。
见下面的HttpService类:
import Cookie from './cookie' export default class HttpService { static query(config) { config = config || {}; var params = HttpService.formatParams(config.data); var request = new XMLHttpRequest(); request.onreadystatechange = function () { if (request.readyState === 4) { var status = request.status; if (status >= 200 && status < 300) { var res = JSON.parse(request.responseText); config.success && config.success(res); } else { //return config.fail && config.fail(status); Cookie.delete('token'); window.location='/'; } } }; request.open('GET', config.url + "?" + params, true); request.setRequestHeader("Authorization", 'Bearer '+Cookie.get('token')); request.send(null); } static jsonp(config) { config = config || {}; var params = HttpService.formatParams(config.data); var Scrip=document.createElement('script'); Scrip.src = config.url + "?" + params + "&jsoncallback=HttpService.jsonpCallback"; this.callback = config.success; document.body.appendChild(Scrip); } static jsonpCallback(e) { this.callback(e); } static save(config) { config = config || {}; var params = HttpService.formatParams(config.data); var request = new XMLHttpRequest(); request.onreadystatechange = function () { if (request.readyState === 4) { var status = request.status; if (status >= 200 && status < 300) { var res = JSON.parse(request.responseText); console.log(res); config.success && config.success(res); } else { //config.fail && config.fail(status); Cookie.delete('token'); window.location='/'; } } }; request.open("POST", config.url, true); request.setRequestHeader("Authorization", 'Bearer '+Cookie.get('token')); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(params); } static uploadFile(cfg) { var config = cfg || {}; var xhr; var fileObj = config.file; // js 获取文件对象 var url = config.url; // 接收上传文件的后台地址 var form = new FormData(); // FormData 对象 form.append(config.name, fileObj); // 文件对象 xhr = new XMLHttpRequest(); // XMLHttpRequest 对象 xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { var status = xhr.status; if (status >= 200 && status < 300) { var res = JSON.parse(xhr.responseText); console.log(res); config.success && config.success(res); } else { config.fail && config.fail(status); } } }; xhr.send(form); //开始上传,发送form数据 } static formatParams(data) { var arr = []; for (var name in data) { arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name])); } arr.push(("v=" + Math.random()).replace(".", "")); return arr.join("&"); } }
然后封装了两个常用的调用方法,api调用时打开数据加载提示,加载出错提示错误信息,加载成功执行成功事件。
static httpsave(url, data, func, showloding) { if (showloding) { CrossComponentAccess.showDataLoading(); } HttpService.save({ url: this.ApiUrl + url, data: data, success: res => { if (showloding) { CrossComponentAccess.hideDataLoading(); } if (res.succeed) { func(res); } else { CrossComponentAccess.showPromptDialog(res.body); } } }); } static httpquery(url, data, func, showloding) { if (showloding) { CrossComponentAccess.showDataLoading(); } HttpService.query({ url: this.ApiUrl + url, data: data, success: res => { if (showloding) { CrossComponentAccess.hideDataLoading(); } if (res.succeed) { func(res); } else { CrossComponentAccess.showPromptDialog(res.body); } } }); }
上面两个方法里面的CrossComponentAccess类,通过事件通知调用显示数据加载提升和操作完的提示。
所有的对服务端的api访问都是在下面ServerApi这个类里面的。调用成功后使用通知中心EventNotificationCenter把数据广播出去
import HttpService from './http-service'; import EventNames from '../config/event-names' import EventNotificationCenter from './event-notification-center' import CrossComponentAccess from './cross-component-access' export default class ServerApi { static ApiUrl = "http://118.25.217.253:8010"; //static ApiUrl = "http://localhost:53418"; //static ApiUrl = "http://118.25.217.253:4010"; static httpsave(url, data, func, showloding) { if (showloding) { CrossComponentAccess.showDataLoading(); } HttpService.save({ url: this.ApiUrl + url, data: data, success: res => { if (showloding) { CrossComponentAccess.hideDataLoading(); } if (res.succeed) { func(res); } else { CrossComponentAccess.showPromptDialog(res.body); } } }); } static httpquery(url, data, func, showloding) { if (showloding) { CrossComponentAccess.showDataLoading(); } HttpService.query({ url: this.ApiUrl + url, data: data, success: res => { if (showloding) { CrossComponentAccess.hideDataLoading(); } if (res.succeed) { func(res); } else { CrossComponentAccess.showPromptDialog(res.body); } } }); } static login(loginName, password) { this.httpsave('/User/Login', { loginName: loginName, password: password }, res => { EventNotificationCenter.send(EventNames.OnLoginBack, { uid: res.body.user.id, uname: res.body.user.loginName, uroles: res.body.user.roles, token: res.body.token }); }, true); } static listDataPage(apicontroller, searchText, currentPage, pageSize, urlpars) { this.httpquery('/' + apicontroller + '/List', { searchText: searchText, pageIndex: currentPage, pageSize: pageSize, urlpar: urlpars }, res => { EventNotificationCenter.send(apicontroller + "_List", res.body); if (apicontroller === "Knowledge") { EventNotificationCenter.send(EventNames.KnowledgeCategoryMenu, res.body.category); } if (apicontroller === "KnowledgeCategory") { EventNotificationCenter.send(EventNames.KnowledgeCategoryMenu, res.body.dataSource); } if (apicontroller === "FlowAccount") { EventNotificationCenter.send(EventNames.BankAccountMenu, res.body.allBankAccount); } if (apicontroller === "BankAccount") { EventNotificationCenter.send(EventNames.BankAccountMenu, res.body.dataSource); } if (apicontroller === "AdvertisingCompany") { EventNotificationCenter.send(EventNames.ADMenu, res.body.dataSource); } if (apicontroller === "AdvertisingSpace") { EventNotificationCenter.send(EventNames.ADMenu, res.body.company); } if (apicontroller === "Task") { EventNotificationCenter.send(EventNames.TaskMenu, res.body.allExecutor); } }, false); } static deleteDataPage(apicontroller, ids) { this.httpsave('/' + apicontroller + '/Delete', { ids: ids }, res => { EventNotificationCenter.send(apicontroller + "_Delete", res.body); }, true); } static saveDataPage(apicontroller, data) { this.httpsave('/' + apicontroller + '/Save', data, res => { EventNotificationCenter.send(apicontroller + "_Save", res.body); }, true); } static infoDataPage(apicontroller, id, par) { this.httpquery('/' + apicontroller + '/Get', { id: id, par: par }, res => { EventNotificationCenter.send(apicontroller + "_Get", res.body); }, true); } static listFlowAccount(urlpars, project, flowCategory, beginTime, endTime, currentPage, pageSize) { if (beginTime !== undefined && beginTime !== "" && endTime !== undefined && endTime !== "") { this.httpquery('/FlowAccount/List', { urlpar: urlpars, project: project, flowCategory: flowCategory, beginTime: beginTime, endTime: endTime, pageIndex: currentPage, pageSize: pageSize }, res => { EventNotificationCenter.send("FlowAccount_List", res.body); EventNotificationCenter.send(EventNames.BankAccountMenu, res.body.allBankAccount); }, false); } else { this.httpquery('/FlowAccount/List', { urlpar: urlpars, project: project, flowCategory: flowCategory, pageIndex: currentPage, pageSize: pageSize }, res => { EventNotificationCenter.send("FlowAccount_List", res.body); EventNotificationCenter.send(EventNames.BankAccountMenu, res.body.allBankAccount); }, false); } } static listTask(excutorID, projectID, taskStepID, currentPage, pageSize, isClosed) { this.httpquery('/Task/List', { excutorID: excutorID, projectID: projectID, taskStepID: taskStepID, isClosed: isClosed, pageIndex: currentPage, pageSize: pageSize }, res => { EventNotificationCenter.send("Task_List", res.body); EventNotificationCenter.send(EventNames.TaskMenu, res.body.allExecutor); }, false); } static closeTask(ids) { this.httpsave('/Task/Close', { ids: ids }, res => { EventNotificationCenter.send("Task_Close", res.body); }, true); } }
这章http访问里,涉及到Cookie和通知中心EventNotificationCenter在下一章介绍。