index.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * FeHelper 简易版Postman
  3. */
  4. // json with bigint supported
  5. Tarp.require('../static/vendor/json-bigint/index');
  6. new Vue({
  7. el: '#pageContainer',
  8. data: {
  9. urlContent: '',
  10. urlParams: [],
  11. methodContent: 'GET',
  12. resultContent: '',
  13. paramContent: '',
  14. responseHeaders: [],
  15. jfCallbackName_start: '',
  16. jfCallbackName_end: '',
  17. errorMsgForJson: ''
  18. },
  19. watch: {
  20. urlContent: function (val) {
  21. let url = val;
  22. let reg = /[?&]([^?&#]+)=([^?&#]*)/g;
  23. let params = [];
  24. let ret = reg.exec(url);
  25. while (ret) {
  26. params.push({
  27. key: ret[1],
  28. value: ret[2],
  29. });
  30. ret = reg.exec(url);
  31. }
  32. const originStr = this.urlParams2String(params);
  33. const newStr = this.urlParams2String(this.urlParams);
  34. if (originStr !== newStr) {
  35. this.urlParams = params;
  36. }
  37. },
  38. urlParams: {
  39. handler(val) {
  40. this.urlContent =
  41. this.urlContent.substr(0, this.urlContent.indexOf("?") + 1) +
  42. val.map((item) => `${item.key}=${item.value}`).join("&");
  43. },
  44. deep: true,
  45. },
  46. },
  47. mounted: function () {
  48. this.$refs.url.focus();
  49. },
  50. methods: {
  51. postman: function () {
  52. this.$nextTick(() => {
  53. this.sendRequest(this.urlContent, this.methodContent, this.paramContent);
  54. });
  55. },
  56. sendRequest: function (url, method, body) {
  57. let xhr = new XMLHttpRequest();
  58. xhr.addEventListener("readystatechange", (resp) => {
  59. let result = 'Loading...';
  60. switch (resp.target.readyState) {
  61. case resp.target.OPENED:
  62. result = 'Senting...';
  63. break;
  64. case resp.target.HEADERS_RECEIVED:
  65. result = 'Headers received';
  66. this.responseHeaders = resp.target.getAllResponseHeaders().trim().split('\n').map(item => {
  67. return item.split(': ').map(x => x.trim())
  68. });
  69. break;
  70. case resp.target.LOADING:
  71. result = 'Loading...';
  72. break;
  73. case resp.target.DONE:
  74. try {
  75. result = JSON.stringify(JSON.parse(resp.target.responseText), null, 4);
  76. } catch (e) {
  77. result = resp.target.responseText;
  78. }
  79. this.jsonFormat(result);
  80. this.renderTab();
  81. break;
  82. }
  83. this.resultContent = result || '无数据';
  84. });
  85. xhr.open(method, url);
  86. if(method.toLowerCase() === 'post') {
  87. xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
  88. xhr.send(body);
  89. }else{
  90. xhr.send();
  91. }
  92. },
  93. renderTab: function () {
  94. jQuery('#tabs').tabs({
  95. show: (event, ui) => {
  96. }
  97. });
  98. this.$refs.resultContainer.classList.remove('hide');
  99. },
  100. jsonFormat: function (source) {
  101. this.errorMsgForJson = '';
  102. this.jfCallbackName_start = '';
  103. this.jfCallbackName_end = '';
  104. if (!source) {
  105. return false;
  106. }
  107. // JSONP形式下的callback name
  108. let funcName = null;
  109. // json对象
  110. let jsonObj = null;
  111. // 下面校验给定字符串是否为一个合法的json
  112. try {
  113. // 再看看是不是jsonp的格式
  114. let reg = /^([\w\.]+)\(\s*([\s\S]*)\s*\)$/igm;
  115. let matches = reg.exec(source);
  116. if (matches != null) {
  117. funcName = matches[1];
  118. source = matches[2];
  119. }
  120. // 这里可能会throw exception
  121. jsonObj = JSON.parse(source);
  122. } catch (ex) {
  123. // new Function的方式,能自动给key补全双引号,但是不支持bigint,所以是下下策,放在try-catch里搞
  124. try {
  125. jsonObj = new Function("return " + source)();
  126. } catch (exx) {
  127. try {
  128. // 再给你一次机会,是不是下面这种情况: "{\"ret\":\"0\", \"msg\":\"ok\"}"
  129. jsonObj = new Function("return '" + source + "'")();
  130. if (typeof jsonObj === 'string') {
  131. // 最后给你一次机会,是个字符串,老夫给你再转一次
  132. jsonObj = new Function("return " + jsonObj)();
  133. }
  134. } catch (exxx) {
  135. this.errorMsgForJson = exxx.message;
  136. }
  137. }
  138. }
  139. // 是json格式,可以进行JSON自动格式化
  140. if (jsonObj != null && typeof jsonObj === "object" && !this.errorMsgForJson.length) {
  141. try {
  142. // 要尽量保证格式化的东西一定是一个json,所以需要把内容进行JSON.stringify处理
  143. source = JSON.stringify(jsonObj);
  144. } catch (ex) {
  145. // 通过JSON反解不出来的,一定有问题
  146. this.errorMsgForJson = ex.message;
  147. }
  148. if (!this.errorMsgForJson.length) {
  149. // 格式化
  150. Tarp.require('../json-format/format-lib').format(source);
  151. // 如果是JSONP格式的,需要把方法名也显示出来
  152. if (funcName != null) {
  153. this.jfCallbackName_start = funcName + '(';
  154. this.jfCallbackName_end = ')';
  155. } else {
  156. this.jfCallbackName_start = '';
  157. this.jfCallbackName_end = '';
  158. }
  159. }
  160. }
  161. // 不是json,都格式化不了,一定会出错
  162. if (this.errorMsgForJson) {
  163. let el = document.querySelector('#optionBar');
  164. el && (el.style.display = 'none');
  165. }
  166. },
  167. setDemo: function (type) {
  168. if (type === 1) {
  169. this.urlContent = 'https://www.sojson.com/api/qqmusic/8446666/json';
  170. this.methodContent = 'GET';
  171. } else {
  172. this.urlContent = 'https://www.baidufe.com/test-post.php';
  173. this.methodContent = 'POST';
  174. this.paramContent = 'username=postman&password=123456'
  175. }
  176. },
  177. urlParams2String: function (params) {
  178. return params.map((param) => `${param.key}=${param.value}`).join("&")
  179. }
  180. }
  181. });