request.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. * @Author: Rindy
  3. * @Date: 2019-08-06 16:25:08
  4. * @LastEditors: Rindy
  5. * @LastEditTime: 2021-08-27 12:33:49
  6. * @Description: Request
  7. */
  8. /** http请求模块
  9. * @category utils
  10. * @module utils/request
  11. */
  12. import browser from "./browser.js"
  13. import { base64ToBlob } from "./file.js"
  14. //import { $alert, $confirm, $loginTips } from "@/components/shared/message"
  15. //import { $waiting } from "@/components/shared/loading"
  16. //import { checkLogin } from "@/api"
  17. //import { LoginDetector } from "@/core/starter"
  18. //import { i18n } from "@/lang"
  19. //import { password } from "@/utils/string"
  20. //import store from "../Store"
  21. // 空函数
  22. const noop = function() {}
  23. // 请求回调队列
  24. let postQueue = []
  25. /**
  26. * @property {number} NEXT - 继续执行
  27. * @property {number} SUCCESS - 成功
  28. * @property {number} EXCEPTION - 异常错误
  29. * @property {number} FAILURE_CODE_3001 - 缺少必要参数
  30. * @property {number} FAILURE_CODE_3002 - 访问异常
  31. * @property {number} FAILURE_CODE_3003 - 非法访问
  32. * @property {number} FAILURE_CODE_3004 - 用户未登录
  33. * @property {number} FAILURE_CODE_3005 - 验证码已过期
  34. * @property {number} FAILURE_CODE_3006 - 验证码错误
  35. * @property {number} FAILURE_CODE_3007 - 昵称已存在
  36. * @property {number} FAILURE_CODE_3008 - 该手机已被注册
  37. * @property {number} FAILURE_CODE_3009 - 两次输入的密码不一致
  38. * @property {number} FAILURE_CODE_3010 - 昵称长度错误
  39. * @property {number} FAILURE_CODE_3011 - 密码长度错误
  40. * @property {number} FAILURE_CODE_3012 - 昵称包含敏感词
  41. * @property {number} FAILURE_CODE_3013 - 手机号码格式错误
  42. * @property {number} FAILURE_CODE_3014 - 账号或密码不正确
  43. * @property {number} FAILURE_CODE_3015 - 用户不存在
  44. * @property {number} FAILURE_CODE_3016 - 您没有权限,请联系管理员
  45. * @property {number} FAILURE_CODE_3017 - 空文件
  46. * @property {number} FAILURE_CODE_3018 - 需要上传或使用的文件不存在
  47. * @property {number} FAILURE_CODE_5010 - 找不到该场景对应的相机
  48. * @property {number} FAILURE_CODE_5012 - 数据不正常
  49. * @property {number} FAILURE_CODE_5014 - 无权操作该场景
  50. * @property {number} FAILURE_CODE_5005 - 场景不存在
  51. */
  52. export const statusCode = {
  53. NEXT: -999,
  54. SUCCESS: 0,
  55. EXCEPTION: -1,
  56. FAILURE_CODE_3001: 3001,
  57. FAILURE_CODE_3002: 3002,
  58. FAILURE_CODE_3003: 3003,
  59. FAILURE_CODE_3004: 3004,
  60. FAILURE_CODE_3005: 3005,
  61. FAILURE_CODE_3006: 3006,
  62. FAILURE_CODE_3007: 3007,
  63. FAILURE_CODE_3008: 3008,
  64. FAILURE_CODE_3009: 3009,
  65. FAILURE_CODE_3010: 3010,
  66. FAILURE_CODE_3011: 3011,
  67. FAILURE_CODE_3012: 3012,
  68. FAILURE_CODE_3013: 3013,
  69. FAILURE_CODE_3014: 3014,
  70. FAILURE_CODE_3015: 3015,
  71. FAILURE_CODE_3016: 3016,
  72. FAILURE_CODE_3017: 3017,
  73. FAILURE_CODE_3018: 3018,
  74. FAILURE_CODE_5010: 5010,
  75. FAILURE_CODE_5012: 5012,
  76. FAILURE_CODE_5014: 5014,
  77. FAILURE_CODE_5005: 5005,
  78. }
  79. /**
  80. * 获取Token
  81. * @function
  82. */
  83. export function getToken() {
  84. var urlToken = browser.urlHasValue("token", true)
  85. if (urlToken) {
  86. // 设置token共享给用户中心
  87. localStorage.setItem("token", urlToken)
  88. }
  89. return urlToken || localStorage.getItem("token") || ""
  90. }
  91. /**
  92. * 根据状态码的结果处理后续操作
  93. * @function
  94. * @param {number} code - 状态码
  95. * @param {function} callback - 回调
  96. */
  97. export function statusCodesHandler(code, callback) {
  98. if (code == statusCode.EXCEPTION) {
  99. return $alert({ content: i18n.t("tips.exception") })
  100. }
  101. if (
  102. code == statusCode.FAILURE_CODE_3002 ||
  103. code == statusCode.FAILURE_CODE_3003 ||
  104. code == statusCode.FAILURE_CODE_3004
  105. ) {
  106. callback(code)
  107. return showLoginTips()
  108. }
  109. if (code == statusCode.FAILURE_CODE_3001) {
  110. callback(code)
  111. return $alert({ content: i18n.t("tips.params_notfound") })
  112. }
  113. if (code == statusCode.FAILURE_CODE_3017) {
  114. callback(code)
  115. return $alert({ content: i18n.t("tips.file_notfound") })
  116. }
  117. if (code == statusCode.FAILURE_CODE_5005) {
  118. /* if (!config.isEdit) {
  119. return (location.href = config.pages.NotFound)
  120. } */
  121. callback(code)
  122. return $alert({ content: i18n.t("tips.scene_notfound") })
  123. }
  124. if (code == statusCode.FAILURE_CODE_5010) {
  125. callback(code)
  126. return $alert({ content: i18n.t("tips.camera_notfound") })
  127. }
  128. if (code == statusCode.FAILURE_CODE_5012) {
  129. callback(code)
  130. return $alert({ content: i18n.t("tips.data_error") })
  131. }
  132. if (code == statusCode.FAILURE_CODE_5014) {
  133. callback(code)
  134. return $alert({ content: i18n.t("tips.auth_deny") })
  135. }
  136. return statusCode.NEXT
  137. }
  138. $.ajaxSetup({
  139. headers: {},
  140. beforeSend: function(xhr) {
  141. const token = getToken()
  142. if (token) {
  143. xhr.setRequestHeader("token", token)
  144. } else if (!token && this.url.indexOf("isLogin") != -1) {
  145. showLoginTips()
  146. }
  147. /* if (config.oem == "localshow") {
  148. // 本地版本兼容当前目录
  149. if (this.url.indexOf("http") == -1 && this.url.indexOf("/") == 0) {
  150. this.url = this.url.substr(1)
  151. }
  152. } */
  153. // if(this.url.indexOf('http')==-1 && this.url.indexOf('/') !=0){
  154. // this.url = '/'+this.url
  155. // }
  156. },
  157. error: function(xhr, status, error) {
  158. // 出错时默认的处理函数
  159. if (this.url.indexOf("/scene.json") != -1 && xhr.status == 404) {
  160. return $alert({ content: i18n.t("tips.scene_notfound") })
  161. } else if (this.type === "POST") {
  162. return $alert({ content: i18n.t("tips.network_error") })
  163. }
  164. },
  165. success: function(result) {},
  166. complete: function() {
  167. // Post类型请求无论成功或失败都关闭等待提示
  168. if (this.type === "POST") {
  169. http.__loading && $waiting.hide()
  170. }
  171. http.__loading = true
  172. },
  173. })
  174. /**
  175. * @namespace http
  176. * @type {Object}
  177. */
  178. export const http = {
  179. statusCode,
  180. __loading: true,
  181. __request(xhr, method, url, data, done, fail) {
  182. if (typeof done != "function") {
  183. done = noop
  184. }
  185. if (typeof fail != "function") {
  186. fail = noop
  187. }
  188. xhr.done(result => {
  189. if (typeof result.code !== "undefined") {
  190. const flag = statusCodesHandler(result.code, function(code) {
  191. // 需要登录的状态
  192. if (
  193. code == statusCode.FAILURE_CODE_3001 ||
  194. code == statusCode.FAILURE_CODE_3002 ||
  195. code == statusCode.FAILURE_CODE_3003 ||
  196. code == statusCode.FAILURE_CODE_3004
  197. ) {
  198. if (url.indexOf("isLogin") == -1 && url.indexOf("openSceneBykey") == -1) {
  199. postQueue.push(function() {
  200. http[method](url, data, done, fail)
  201. })
  202. }
  203. }
  204. fail()
  205. })
  206. if (flag === statusCode.NEXT) {
  207. done(result, result.code == 0)
  208. }
  209. } else {
  210. done(result)
  211. }
  212. })
  213. xhr.fail(fail)
  214. xhr.always(() => (xhr = null))
  215. return xhr
  216. },
  217. /**
  218. * Get请求
  219. * @param {String} url 请求地址
  220. * @param {Object?} data 请求参数
  221. * @param {Function?} done 成功回调
  222. * @param {Function?} fail 失败回调
  223. */
  224. get(url, data = {}, done, fail) {
  225. if (/\.json/.test(url)) {
  226. // json文件格式自动调用getJson方法
  227. return this.getJson(url, data, done, fail)
  228. }
  229. return this.__request($.get(url, data), "get", url, data, done, fail)
  230. },
  231. /**
  232. * Get Blob请求
  233. * @param {String} url 请求地址
  234. * @param {Object?} data 请求参数
  235. * @param {Function?} done 成功回调
  236. * @param {Function?} fail 失败回调
  237. */
  238. getText(url, data = {}, done, fail) {
  239. return this.__request(
  240. $.ajax({
  241. url: url,
  242. dataType: "text",
  243. }),
  244. "getText",
  245. url,
  246. data,
  247. done,
  248. fail
  249. )
  250. },
  251. /**
  252. * GetJson请求 读取json文件数据
  253. * @param {String} url 请求地址
  254. * @param {Object?} data 请求参数
  255. * @param {Function?} done 成功回调
  256. * @param {Function?} fail 失败回调
  257. */
  258. getJson(url, data = {}, done, fail) {
  259. return this.__request($.getJSON(url, data), "get", url, data, done, fail)
  260. },
  261. /**
  262. * Get Blob请求
  263. * @param {String} url 请求地址
  264. * @param {Object?} data 请求参数
  265. * @param {Function?} done 成功回调
  266. * @param {Function?} fail 失败回调
  267. */
  268. getBlob(url, data = {}, done, fail) {
  269. return this.__request(
  270. $.ajax({
  271. url: url,
  272. dataType: "blob",
  273. }),
  274. "getBlob",
  275. url,
  276. data,
  277. done,
  278. fail
  279. )
  280. },
  281. /**
  282. * Get Arraybuffer请求
  283. * @param {String} url 请求地址
  284. * @param {Object?} data 请求参数
  285. * @param {Function?} done 成功回调
  286. * @param {Function?} fail 失败回调
  287. */
  288. getArraybuffer(url, data = {}, done, fail) {
  289. return this.__request(
  290. $.ajax({
  291. url: url,
  292. dataType: "arraybuffer",
  293. }),
  294. "getArraybuffer",
  295. url,
  296. data,
  297. done,
  298. fail
  299. )
  300. },
  301. /**
  302. * Post 请求
  303. * @param {String} url 请求地址
  304. * @param {Object?} data 请求参数
  305. * @param {Function?} done 成功回调
  306. * @param {Function?} fail 失败回调
  307. */
  308. post(url, data = {}, done, fail) {
  309. if (url.indexOf("isLogin") == -1) {
  310. http.__loading && $waiting.show()
  311. }
  312. return this.__request($.post(url, data), "post", url, data, done, fail)
  313. },
  314. /**
  315. * PostJson 请求
  316. * @param {String} url 请求地址
  317. * @param {Object?} data 请求参数
  318. * @param {Function?} done 成功回调
  319. * @param {Function?} fail 失败回调
  320. */
  321. postJson(url, data = {}, done, fail) {
  322. http.__loading && $waiting.show()
  323. return this.__request(
  324. $.ajax({
  325. type: "POST",
  326. url: url,
  327. contentType: "application/json",
  328. data: JSON.stringify(data),
  329. }),
  330. "postJson",
  331. url,
  332. data,
  333. done,
  334. fail
  335. )
  336. },
  337. /**
  338. * Post 表单 支持文件上传
  339. * @param {String} url 请求地址
  340. * @param {FormData?} formData 请求参数
  341. * @param {Function?} done 成功回调
  342. * @param {Function?} fail 失败回调
  343. */
  344. postForm(url, formData, done, fail, onProgress) {
  345. if (typeof onProgress === "function") {
  346. return this.__request(
  347. $.ajax({
  348. type: "POST",
  349. url: url,
  350. processData: false,
  351. contentType: false,
  352. data: formData,
  353. xhr: function() {
  354. const xhr = new XMLHttpRequest()
  355. xhr.upload.addEventListener("progress", function(e) {
  356. onProgress((e.loaded / e.total) * 100 + "%")
  357. })
  358. return xhr
  359. },
  360. }),
  361. "postForm",
  362. url,
  363. formData,
  364. done,
  365. fail
  366. )
  367. } else {
  368. http.__loading && $waiting.show()
  369. return this.__request(
  370. $.ajax({
  371. type: "POST",
  372. url: url,
  373. processData: false,
  374. contentType: false,
  375. data: formData,
  376. }),
  377. "postForm",
  378. url,
  379. formData,
  380. done,
  381. fail
  382. )
  383. }
  384. },
  385. /**
  386. * 加载图片
  387. * @param {String} url 请求地址
  388. * @param {Number?} retry 重试次数,默认为3
  389. */
  390. loadImage(url, retry = 3) {
  391. const def = $.Deferred()
  392. const img = new Image()
  393. /* if (process.env.VUE_APP_REGION == "AWS" && url.indexOf("x-oss-process=image") != -1) {
  394. var arr = url.split("?")
  395. url = arr[0] + encodeURIComponent("?" + arr[1].replace(/\//g, "@"))
  396. } */
  397. const load = () => {
  398. console.warn("Retrying load image: " + url)
  399. this.loadImage(url, retry - 1)
  400. .done(def.resolve.bind(def))
  401. .progress(def.notify.bind(def))
  402. .fail(def.reject.bind(def))
  403. }
  404. img.onerror = function() {
  405. retry > 0 ? setTimeout(() => load(), 1e3) : def.reject(`[${url}]加载失败`)
  406. }
  407. img.onload = function() {
  408. def.resolve(img)
  409. }
  410. img.crossOrigin = "anonymous"
  411. img.src = url
  412. return def
  413. },
  414. /**
  415. * 上传文件
  416. * @param {String} url 请求地址
  417. * @param {Object?} data 请求参数
  418. * @param {Function?} done 成功回调
  419. * @param {Function?} fail 失败回调
  420. */
  421. uploadFile(url, data = {}, done, fail, onProgress) {
  422. const form = new FormData()
  423. // if (file.needTransfer) { //ie和苹果都不支持dataURLtoFile得传送,所以只能用blob
  424. // form.append("file", common.dataURLtoBlob(file.file), file.name || file.file.name);
  425. // } else {
  426. // form.append("file", file.file, file.name || file.file.name);
  427. // }
  428. for (let key in data) {
  429. if (key == "file") {
  430. form.append("file", data[key], data.filename || data[key].name)
  431. } else if (key != "filename") {
  432. form.append(key, data[key])
  433. }
  434. }
  435. return this.postForm(url, form, done, fail, onProgress)
  436. },
  437. /**
  438. * 上传文件
  439. * @param {String} url 请求地址
  440. * @param {Object?} data 请求参数 {file:'base64 string',filename:'image.jpg',...}
  441. * @param {Function?} done 成功回调
  442. * @param {Function?} fail 失败回调
  443. */
  444. uploadBlobFile(url, data = {}, done, fail) {
  445. const form = new FormData()
  446. for (let key in data) {
  447. if (key === "file") {
  448. form.append("file", base64ToBlob(data.file), data.filename)
  449. } else if (key != "filename") {
  450. form.append(key, data[key])
  451. }
  452. }
  453. return this.postForm(url, form, done, fail)
  454. },
  455. }