request.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /*
  2. * @Author: Rindy
  3. * @Date: 2019-08-06 16:25:08
  4. * @LastEditors: Rindy
  5. * @LastEditTime: 2020-07-29 17:36:36
  6. * @Description: Request
  7. */
  8. import Vue from "vue";
  9. import logger from "./logger";
  10. import browser from "./browser";
  11. import { base64ToBlob } from "./file";
  12. import { checkLogin } from "@/api";
  13. import { LoginDetector } from "@/utils/starter";
  14. import { $alert, $confirm } from "@/components/shared/message";
  15. let vue = new Vue();
  16. // 空函数
  17. const noop = function() {};
  18. // 请求回调队列
  19. let postQueue = [];
  20. export const statusCode = {
  21. NEXT: -999, //继续执行
  22. SUCCESS: 0, //成功
  23. EXCEPTION: -1, //异常错误
  24. FAILURE_CODE_3002: 3002, //请至少保留一个场景。
  25. FAILURE_CODE_3003: 3003, //文件名称不允许超过50个字符
  26. FAILURE_CODE_3005: 3005, //不是该用户作品
  27. FAILURE_CODE_3006: 3006, //作品已被删除,无法编辑
  28. FAILURE_CODE_3007: 3007, //素材已被引用,无法删除。
  29. FAILURE_CODE_5003: 5003, //不支持此图片
  30. FAILURE_CODE_7005: 7005, //审核中不能编辑
  31. FAILURE_CODE_7006: 7006, //已审核不能编辑
  32. FAILURE_CODE_5001: 5001, //token失效
  33. FAILURE_CODE_5004: 5004, // 密码错误
  34. };
  35. /**
  36. * 已知错误提示集合
  37. */
  38. // const defineErrorCode = []
  39. let __showNetworkError = false;
  40. const showLoginTips = () => {
  41. // 防止多次请求弹出
  42. if (showLoginTips.__is_show) {
  43. return;
  44. }
  45. showLoginTips.__is_show = true;
  46. return $confirm({
  47. title: "提示",
  48. content: "您没有登录,请登录后再编辑",
  49. okText: "去登录",
  50. noText: "登录完毕,继续",
  51. okLink: "/",
  52. ok: function() {
  53. showLoginTips.__is_show = false;
  54. return false;
  55. },
  56. no: function() {
  57. checkLogin().then((response) => {
  58. if (response.code === statusCode.SUCCESS) {
  59. postQueue.length && postQueue.forEach((item) => item());
  60. postQueue = [];
  61. LoginDetector.valid();
  62. let url = window.location.href
  63. window.location.href = url
  64. } else if (response.code === statusCode.FAILURE_CODE_5001) {
  65. showLoginTips();
  66. }
  67. });
  68. showLoginTips.__is_show = false;
  69. },
  70. });
  71. };
  72. function getCookie(objname) {
  73. //获取指定名称的cookie的值
  74. var arrstr = document.cookie.split("; ");
  75. for (var i = 0; i < arrstr.length; i++) {
  76. var temp = arrstr[i].split("=");
  77. if (temp[0] == objname) return unescape(temp[1]);
  78. }
  79. }
  80. export function getToken() {
  81. return (
  82. browser.urlHasValue("token", true) || localStorage.getItem("token") || getCookie("fdkankantoken") || ""
  83. );
  84. }
  85. export function statusCodesHandler(result, callback) {
  86. if (result.code == statusCode.FAILURE_CODE_7005) {
  87. return $alert({
  88. content: "该VR作品待审核,不可编辑。",
  89. forceOK: true,
  90. ok: () => {
  91. let url = window.location.href
  92. window.location.href = url
  93. },
  94. });
  95. }
  96. if (result.code == statusCode.FAILURE_CODE_7006) {
  97. return $alert({
  98. content: "该VR作品已审核,不可编辑。",
  99. forceOK: true,
  100. ok: () => {
  101. window.location.reload();
  102. },
  103. });
  104. }
  105. if (result.code == statusCode.FAILURE_CODE_3007) {
  106. return $alert({ content: "素材已被引用,无法删除。" });
  107. }
  108. if (result.code == statusCode.FAILURE_CODE_3002) {
  109. return $alert({ content: "请至少保留一个场景。" });
  110. }
  111. if (result.code == statusCode.FAILURE_CODE_3006) {
  112. return $alert({ content: "作品已被删除,无法编辑" });
  113. }
  114. if (result.code == statusCode.FAILURE_CODE_3005) {
  115. return;
  116. }
  117. if (result.code == statusCode.FAILURE_CODE_3003) {
  118. return statusCode.FILE;
  119. // return $alert({ content: '文件名称不允许超过50个字符' })
  120. }
  121. if (result.code == statusCode.FAILURE_CODE_5003) {
  122. return statusCode.FILE;
  123. // return $alert({ content: '不支持此图片' })
  124. }
  125. if (result.code == statusCode.FAILURE_CODE_5004) {
  126. return $alert({ content: "密码错误" });
  127. }
  128. if (result.code == statusCode.FAILURE_CODE_5001) {
  129. callback(result.code);
  130. return showLoginTips();
  131. }
  132. if (result.code != statusCode.SUCCESS) {
  133. return $alert({ content: `${result.msg}` });
  134. }
  135. return statusCode.NEXT;
  136. }
  137. $.ajaxSetup({
  138. headers: {},
  139. beforeSend: function(xhr) {
  140. const token = getToken();
  141. if (token) {
  142. xhr.setRequestHeader("token", token);
  143. }
  144. },
  145. error: function() {
  146. // 出错时默认的处理函数
  147. if (__showNetworkError) {
  148. return;
  149. }
  150. __showNetworkError = true;
  151. $alert({
  152. content: "网络异常,请稍后再试",
  153. forceOK: true,
  154. ok: () => {
  155. __showNetworkError = false;
  156. },
  157. });
  158. return;
  159. },
  160. success: function() {},
  161. complete: function(data) {
  162. },
  163. });
  164. export const http = {
  165. statusCode,
  166. __request(xhr, method, url, data, done, fail) {
  167. if (typeof done != "function") {
  168. done = noop;
  169. }
  170. if (typeof fail != "function") {
  171. fail = noop;
  172. }
  173. xhr.done((result) => {
  174. if (typeof result.code !== "undefined") {
  175. const flag = statusCodesHandler(result, function(code) {
  176. // 需要登录的状态
  177. if (code == statusCode.FAILURE_CODE_5001) {
  178. postQueue.push(function() {
  179. http[method](url, data, done, fail);
  180. });
  181. // if (url.indexOf('isLogin') == -1) {
  182. // postQueue.push(function() {
  183. // http[method](url, data, done, fail)
  184. // })
  185. // }
  186. }
  187. });
  188. if (!flag) {
  189. return;
  190. }
  191. if (flag === statusCode.FILE) { // 并没有这个值
  192. done(result);
  193. }
  194. if (flag === statusCode.NEXT) {
  195. done(result, result.code == 0);
  196. }
  197. } else {
  198. done(result);
  199. }
  200. });
  201. xhr.fail(fail);
  202. xhr.always(() => (xhr = null));
  203. return xhr;
  204. },
  205. /**
  206. * Get请求
  207. * @param {String} url 请求地址
  208. * @param {Object?} data 请求参数
  209. * @param {Function?} done 成功回调
  210. * @param {Function?} fail 失败回调
  211. */
  212. get(url, data = {}, done, fail) {
  213. if (/\.json/.test(url)) {
  214. // json文件格式自动调用getJson方法
  215. return this.getJson(url, data, done, fail);
  216. }
  217. return this.__request($.get(url, data), "get", url, data, done, fail);
  218. },
  219. /**
  220. * Get Blob请求
  221. * @param {String} url 请求地址
  222. * @param {Object?} data 请求参数
  223. * @param {Function?} done 成功回调
  224. * @param {Function?} fail 失败回调
  225. */
  226. getText(url, data = {}, done, fail) {
  227. return this.__request(
  228. $.ajax({
  229. url: url,
  230. dataType: "text",
  231. }),
  232. "getText",
  233. url,
  234. data,
  235. done,
  236. fail
  237. );
  238. },
  239. /**
  240. * GetJson请求 读取json文件数据
  241. * @param {String} url 请求地址
  242. * @param {Object?} data 请求参数
  243. * @param {Function?} done 成功回调
  244. * @param {Function?} fail 失败回调
  245. */
  246. getJson(url, data = {}, done, fail) {
  247. return this.__request($.getJSON(url, data), "get", url, data, done, fail);
  248. },
  249. /**
  250. * Get Blob请求
  251. * @param {String} url 请求地址
  252. * @param {Object?} data 请求参数
  253. * @param {Function?} done 成功回调
  254. * @param {Function?} fail 失败回调
  255. */
  256. getBlob(url, data = {}, done, fail) {
  257. return this.__request(
  258. $.ajax({
  259. url: url,
  260. dataType: "blob",
  261. }),
  262. "getBlob",
  263. url,
  264. data,
  265. done,
  266. fail
  267. );
  268. },
  269. /**
  270. * Get Arraybuffer请求
  271. * @param {String} url 请求地址
  272. * @param {Object?} data 请求参数
  273. * @param {Function?} done 成功回调
  274. * @param {Function?} fail 失败回调
  275. */
  276. getArraybuffer(url, data = {}, done, fail) {
  277. return this.__request(
  278. $.ajax({
  279. url: url,
  280. dataType: "arraybuffer",
  281. }),
  282. "getArraybuffer",
  283. url,
  284. data,
  285. done,
  286. fail
  287. );
  288. },
  289. /**
  290. * Post 请求
  291. * @param {String} url 请求地址
  292. * @param {Object?} data 请求参数
  293. * @param {Function?} done 成功回调
  294. * @param {Function?} fail 失败回调
  295. */
  296. post(url, data = {}, done, fail) {
  297. return this.__request($.post(url, data), "post", url, data, done, fail);
  298. },
  299. /**
  300. * PostJson 请求
  301. * @param {String} url 请求地址
  302. * @param {Object?} data 请求参数
  303. * @param {Function?} done 成功回调
  304. * @param {Function?} fail 失败回调
  305. */
  306. postJson(url, data = {}, done, fail) {
  307. return this.__request(
  308. $.ajax({
  309. type: "POST",
  310. url: url,
  311. contentType: "application/json",
  312. data: JSON.stringify(data),
  313. }),
  314. "postJson",
  315. url,
  316. data,
  317. done,
  318. fail
  319. );
  320. },
  321. /**
  322. * Post 表单 支持文件上传
  323. * @param {String} url 请求地址
  324. * @param {FormData?} formData 请求参数
  325. * @param {Function?} done 成功回调
  326. * @param {Function?} fail 失败回调
  327. */
  328. postForm(url, formData, done, fail, onProgress) {
  329. if (typeof onProgress === "function") {
  330. return this.__request(
  331. $.ajax({
  332. type: "POST",
  333. url: url,
  334. processData: false,
  335. contentType: false,
  336. data: formData,
  337. xhr: function() {
  338. const xhr = new XMLHttpRequest();
  339. xhr.upload.addEventListener("progress", function(e) {
  340. onProgress(e.loaded / e.total);
  341. });
  342. xhr.onabort = () => {
  343. console.log('xhr aborted.');
  344. }
  345. return xhr;
  346. },
  347. // 覆盖全局配置的失败回调。因为无论是上传子集失败还是用户取消了上传,都不需要弹窗。
  348. error: function() {
  349. },
  350. }),
  351. "postForm",
  352. url,
  353. formData,
  354. done,
  355. fail
  356. );
  357. } else {
  358. return this.__request(
  359. $.ajax({
  360. type: "POST",
  361. url: url,
  362. processData: false,
  363. contentType: false,
  364. data: formData,
  365. }),
  366. "postForm",
  367. url,
  368. formData,
  369. done,
  370. fail
  371. );
  372. }
  373. },
  374. /**
  375. * 加载图片
  376. * @param {String} url 请求地址
  377. * @param {Number?} retry 重试次数,默认为3
  378. */
  379. loadImage(url, retry = 3) {
  380. const def = $.Deferred();
  381. const img = new Image();
  382. const load = () => {
  383. logger.warn("Retrying load image: " + url);
  384. this.loadImage(url, retry - 1)
  385. .done(def.resolve.bind(def))
  386. .progress(def.notify.bind(def))
  387. .fail(def.reject.bind(def));
  388. };
  389. img.onerror = function() {
  390. retry > 0
  391. ? setTimeout(() => load(), 1e3)
  392. : def.reject(`[${url}]加载失败`);
  393. };
  394. img.onload = function() {
  395. def.resolve(img);
  396. };
  397. img.crossOrigin = "anonymous";
  398. img.src = url;
  399. return def;
  400. },
  401. /**
  402. * 上传文件
  403. * @param {String} url 请求地址
  404. * @param {Object?} data 请求参数
  405. * @param {Function?} done 成功回调
  406. * @param {Function?} fail 失败回调
  407. */
  408. uploadFile(url, data = {}, done, fail, onProgress) {
  409. const form = new FormData();
  410. // if (file.needTransfer) { //ie和苹果都不支持dataURLtoFile得传送,所以只能用blob
  411. // form.append("file", common.dataURLtoBlob(file.file), file.name || file.file.name);
  412. // } else {
  413. // form.append("file", file.file, file.name || file.file.name);
  414. // }
  415. for (let key in data) {
  416. if (key == "file") {
  417. form.append("file", data[key], data.filename || data[key].name);
  418. } else if (key != "filename") {
  419. form.append(key, data[key]);
  420. }
  421. }
  422. return this.postForm(url, form, done, fail, onProgress);
  423. },
  424. /**
  425. * 上传文件
  426. * @param {String} url 请求地址
  427. * @param {Object?} data 请求参数 {file:'base64 string',filename:'image.jpg',...}
  428. * @param {Function?} done 成功回调
  429. * @param {Function?} fail 失败回调
  430. */
  431. uploadBlobFile(url, data = {}, done, fail) {
  432. const form = new FormData();
  433. for (let key in data) {
  434. if (key === "file") {
  435. form.append("file", base64ToBlob(data.file), data.filename);
  436. } else if (key != "filename") {
  437. form.append(key, data[key]);
  438. }
  439. }
  440. return this.postForm(url, form, done, fail);
  441. },
  442. };