electron+vue2:发送请求

打印 上一主题 下一主题

主题 1722|帖子 1722|积分 5170

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、electron+axios
1、碰到的题目:在渲染进程中使用axios会出现跨域题目
2、办理办法:
1)修改渲染进程的html页面CSP规则,保存self同源,另外添加详细的接口服务地址
毛病


  • 1、修改CSP规则以答应特定的外部资源访问可能会降低应用的安全性,特别是当答应非同源的资源访问时,应用可能更容易受到跨站脚本攻击(XSS)和其他类型的安全威胁。
  • 2、Electron的未来版本可能会对安全性进行进一步的加强或调整,因此依赖于当前CSP规则的设置可能会在未来的版本中失效或不再被支持
  • 3、不同Electron版本或不同浏览器引擎对CSP规则的支持存在差别,另外Electron在不同的平台上运行(如Windows、macOS、Linux)等,需确保CSP规则都能支持和应用
2)使用electron署理发送请求,参考文章electron使用axios办理cors题目
缺点:如许的请求方式 在控制台是看不到请求的 调试非常不方便,无法处理惩罚复杂的请求,例如,上传文件需要通报FormData格式的数据,而Electron的IPC机制要求发送的数据必须可以或许被布局化克隆算法克隆(数据被序列化),例如函数、Symbol或循环引用的对象,以及某些类型的对象(File,Blob等)会导致请求报错:IpcRenderer.invoke Error: An object could not be cloned (使用ipcMain.handle发送不能被克隆)
使用: 创建一个http.js
  1. import { ipcMain,dialog } from "electron";
  2. import axios from "axios";
  3. const BASE_URL = 'http://xx.xx'
  4. const Headers = {
  5.   Accept: "application/json, text/plain, */*"
  6. }
  7. export const http = () => {
  8.   ipcMain.handle("http-request", async (e, { url, method, data, params,headers}) => {
  9.     const _url = BASE_URL + url;
  10.     const _data = data?data:null
  11.     const _params = params?params:null
  12.     const _method =  method;
  13.     try {
  14.       let response = null;
  15.       if (_method === "POST") {
  16.         response = await axios({
  17.           method:_method,
  18.           url: _url,
  19.           data: _data,
  20.           headers: Headers,
  21.         });
  22.       } else {
  23.         response = await axios({
  24.           method:_method,
  25.           url: _url,
  26.           params: _params,
  27.           headers: Headers,
  28.         });
  29.       }
  30.       return { data: response.data  };
  31.     } catch (err) {
  32.       return { error: err.message };
  33.     }
  34.   });
  35. };
复制代码
在background.js中引入
  1. import http from './http.js'
  2. http()
复制代码
在渲染进程中使用
  1. //this.$electron是在main.js中绑定到了Vue.prototype上面
  2. //const electron = window.require('electron')
  3. //Vue.prototype.$electron = electron
  4. const res = await this.$electron.ipcRenderer.invoke('http-request', {
  5.         url: '/system/auth/login',
  6.         method: 'POST',
  7.         data: {
  8.           password: "xxxx",
  9.           username: "xxxx",
  10.          }
  11.       })
复制代码
使用这种方式不会有跨域的题目,但是只能处理惩罚简单的数据请求,且不方便打印调试
3)使用fetch发送请求
是 ES6 引入的新的 API,现代浏览器基本都支持,但在一些旧版本浏览器中需要使用 polyfill 来实现兼容。
使用:创建一个http.js
  1. class ApiClient {
  2.     constructor(baseURL, options = {}) {
  3.       this.baseURL = baseURL;
  4.       this.defaultOptions = {
  5.         timeout: 30000,
  6.         credentials: 'include',
  7.         ...options
  8.       };
  9.       
  10.       // 请求拦截器
  11.       this.requestInterceptors = [];
  12.       // 响应拦截器
  13.       this.responseInterceptors = [];
  14.     }
  15.    
  16.     /**
  17.      * 核心请求方法
  18.      */
  19.     async _fetch(url, options) {
  20.       // 合并配置
  21.       const mergedOptions = {
  22.         ...this.defaultOptions,
  23.         ...options,
  24.         headers: {
  25.           ...this.defaultOptions.headers,
  26.           ...options.headers
  27.         }
  28.       };
  29.       
  30.       // 应用请求拦截器
  31.       for (const interceptor of this.requestInterceptors) {
  32.         await interceptor(mergedOptions);
  33.       }
  34.       
  35.       // 设置超时
  36.       const controller = new AbortController();
  37.       const timeoutId = setTimeout(() => controller.abort(), mergedOptions.timeout);
  38.       
  39.       try {
  40.         const fullUrl = this.baseURL ? `${this.baseURL}${url}` : url;
  41.         const response = await fetch(fullUrl, {
  42.           ...mergedOptions,
  43.           signal: controller.signal
  44.         });
  45.         
  46.         clearTimeout(timeoutId);
  47.         
  48.         // 应用响应拦截器
  49.         let processedResponse = response;
  50.         for (const interceptor of this.responseInterceptors) {
  51.           processedResponse = await interceptor(processedResponse);
  52.         }
  53.         
  54.         if (!processedResponse.ok) {
  55.           const errorData = await this._parseError(processedResponse);
  56.           throw new HttpError(
  57.             processedResponse.status,
  58.             errorData.message || 'Request failed',
  59.             errorData
  60.           );
  61.         }
  62.         
  63.         return this._parseResponse(processedResponse);
  64.       } catch (error) {
  65.         clearTimeout(timeoutId);
  66.         if (error.name === 'AbortError') {
  67.           throw new HttpError(408, 'Request timeout');
  68.         }
  69.         throw error;
  70.       }
  71.     }
  72.    
  73.     // 添加拦截器
  74.     addRequestInterceptor(interceptor) {
  75.       this.requestInterceptors.push(interceptor);
  76.     }
  77.    
  78.     addResponseInterceptor(interceptor) {
  79.       this.responseInterceptors.push(interceptor);
  80.     }
  81.    
  82.     // 快捷方法
  83.     get(url, options = {}) {
  84.       return this._fetch(url, { ...options, method: 'GET' });
  85.     }
  86.    
  87.     post(url, body, options = {}) {
  88.       return this._fetch(url, {
  89.         ...options,
  90.         method: 'POST',
  91.         body: JSON.stringify(body),
  92.         headers:{
  93.                         'Content-Type':'application/json'
  94.                 }
  95.       });
  96.     }
  97.    
  98.     put(url, body, options = {}) {
  99.       return this._fetch(url, {
  100.         ...options,
  101.         method: 'PUT',
  102.         body: JSON.stringify(body)
  103.       });
  104.     }
  105.    
  106.     delete(url, options = {}) {
  107.       return this._fetch(url, { ...options, method: 'DELETE' });
  108.     }
  109.    
  110.     // 文件上传
  111.     upload(url, formData, options = {}) {
  112.       const headers = {
  113.         ...options.headers,
  114.       };
  115.       delete headers['Content-Type'];
  116.       
  117.       return this._fetch(url, {
  118.         ...options,
  119.         method: 'POST',
  120.         body: formData,
  121.         headers
  122.       });
  123.     }
  124.    
  125.     // 解析响应
  126.     async _parseResponse(response) {
  127.       const contentType = response.headers.get('content-type') || '';
  128.       
  129.       if (contentType.includes('application/json')) {
  130.         return response.json();
  131.       }
  132.       if (contentType.includes('text/')) {
  133.         return response.text();
  134.       }
  135.       return response.blob();
  136.     }
  137.    
  138.     // 解析错误
  139.     async _parseError(response) {
  140.       try {
  141.         return await response.json();
  142.       } catch {
  143.         return { message: response.statusText };
  144.       }
  145.     }
  146.   }
  147.   
  148.   const Http = new ApiClient(ELECTRON_CONFIG.AXIOS_URL);
  149.   
  150.   // 添加请求拦截器
  151.   Http.addRequestInterceptor(async (options) => {
  152.    //请求拦截添加token
  153.   });
  154.   
  155.   // 添加响应拦截器
  156.   Http.addResponseInterceptor(async (response) => {
  157.      return response;
  158.   });
  159.   
  160.   export default Http
  161.   
复制代码
在main.js中引入
  1. import Http from '@/Http/http'
  2. Vue.prototype.$Http = Http
复制代码
发送请求
  1. const res = await this.$Http.upload('xxx',data)
  2. if(res.code == 500){
  3.    this.$message.error(res.msg)
  4.       return
  5. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表