包阅导读总结
1.
关键词:低代码平台、接口跨域、转发接口、后端实现、解决方案
2.
总结:小伙伴在使用低代码平台 marsview 搭建页面时遇到接口跨域问题,由于诸多常规方案不可用,最终通过开发后端转发接口解决,前端进行相应配置修改,经线上验证有效,此思路为解决跨域问题提供了新方法。
3.
– 问题背景
– 小伙伴使用低代码平台 marsview 搭建页面时发现接口跨域问题。
– 因低代码的特殊性,常用跨域方案无法使用。
– 解决方案
– 开发转发接口,由后端实现接口转发,透传参数和请求头信息。
– 前端配置接口时开启代理,修改请求拦截器。
– 后端实现
– 封装 request 类,处理 get 和 post 请求。
– 定义服务访问路由,处理 get 和 post 请求的参数和返回值。
– 线上验证
– 拖拽按钮配置事件流调用第三方登录接口,发送请求成功。
– 测试 post 请求成功,解决了跨域问题。
– 总结
常规跨域方案在某些情况下难以实施,此低代码平台跨域问题解决思路具有较好效果。
思维导图:
文章地址:https://juejin.cn/post/7408775736797200418
文章来源:juejin.cn
作者:河畔一角
发布时间:2024/8/31 13:18
语言:中文
总字数:1854字
预计阅读时间:8分钟
评分:90分
标签:跨域问题,低代码平台,接口转发,前端开发,后端开发
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
背景
最近小伙伴在使用低代码平台marsview
搭建页面时,发现一个接口跨域问题。
当在marsview
创建的页面里面,配置第三方接口时,由于第三方接口不支持跨域,导致低代码页面请求报错,这个问题怎么处理? 如果不解决,可能用户就无法使用这个平台来搭建页面了。
于是,我思考了一下,跨域虽然有很多方案,但是,由于低代码的特殊性,很多方案是无法使用的,比如:nginx
反向代理,后端设置CORS
、iframe
、JSONP
等等。
为什么不能用? 因为低代码配置的第三方接口都是不确定的,你不知道用户会添加什么接口,也就无法再nginx
里面做反向代理,同时第三方的接口我们并没有自主权,对方未必会配合我添加CORS
,那我该怎么办?
解决方案
既然搭建是基于marsview
低代码平台搭建的页面,那问题自然由低代码平台解决,我的方案是开发一个转发接口,由自己的后端去实现接口转发,把参数、请求头等关键信息全部透传过去,毕竟后端调用后端不会出现跨域问题,最终把第三方接口返回的值再返回给低代码平台。
上面是实现功能前,低代码配置的第三方接口跨域报错截图。
前端实现
一、前端配置接口时,开启接口代理。
其他配置方式都不变,只需要开启代理配置即可。
二、修改请求拦截器
instance.interceptors.request.use((config) => { ... config.headers = { ...config.headers, proxyApi: config.isCors ? config.url : '', }; if (config.isCors) { config.url = `${import.meta.env.VITE_BASE_API}/ai/proxy`; } ... return config;});
这里面有几个关键信息。
- 当开启代理后,拦截器中的
config
会拿到一个isCors
参数,我们获取到第三方接口的请求地址添加到请求头中,字段定义为:proxyApi
。 - 修改当前接口的
url
为自己后端的转发接口。也就是让当前的请求调用自己的后端接口。
前端一共就修改这两处即可,剩下的就交给后端处理。
后端实现
假设你已经会使用Koa
开发服务,我们定义一个代理接口,来实现第三方接口转发。
一、简单封装一个request
const { Axios } = require("axios");class Request { constructor(config) { this.instance = new Axios({ baseURL: config.baseURL || "", timeout: 8000, timeoutErrorMessage: "请求超时", withCredentials: true, headers: { "Content-Type": "application/json", }, }); } get(url, params, config = {}) { return this.instance.get(url, { params, ...config }); } post(url, params, config = {}) { return this.instance.post(url, params, config); }}module.exports = new Request({});
封装两个常用的get
和post
请求,把参数和配置都提前处理好。比如get
使用params
,post
直接传参数,另外增加一个自定义的config
以防后期参数扩展。
二、定义服务访问路由
router.get("/proxy", async (ctx) => { try { const { query, headers: { host, proxyapi, ...headers }, } = ctx.request; const response = await request.get(proxyapi, query || {}, { headers, }); const res = JSON.parse(response.data); ctx.body = res; } catch (error) { util.fail(ctx, 500, "接口请求失败"); }});
我们先定义一个get
路由,这里有几个关键信息。
get
请求,从query
里面拿到当前平台接口调用的参数。- 从请求头拿到代理地址和请求头的其它参数,比如:
proxyapi
和authorization
等字段。这里前端虽然传的是大写,但后端获取的请求头均为小写。 - 请求头需要排除
host
字段,这个如果加进去,会影响服务调用。 - 把第三方接口返回值输出给前端。
三、定义POST请求
为了保证不管是get
还是post
接口都能实现转发,我们需要复制一个post
请求。
router.post("/proxy", async (ctx) => { try { const { body, headers: { host, proxyapi, ...headers }, } = ctx.request; const response = await request.post(proxyapi, JSON.stringify(body || {}), { headers, }); const res = JSON.parse(response.data); ctx.body = res; } catch (error) { util.fail(ctx, 500, "接口请求失败"); }});
跟get
基本一样,只是取值有变化,post
请求需要从ctx.request.body
取值,另外针对参数需要通过JSON.stringify(body || {})
转一下。
线上验证
一、拖拽一个按钮,配置一个事件流,调用一个第三方登录接口
二、点击后通过事件流,发送请求
我们会发现,平台发送出去的接口是:/api/ai/proxy
,同时在请求头中添加了proxyApi
参数,值为第三方接口地址,接口返回了对应的数据。
三、测试post
请求
- 添加第三方
post
接口地址,开启代理配置。
- 配置按钮的事件流
- 点击发送请求测试
我们看到发送了一个post
请求出去了,地址是我们开发的后端代理服务。
第三方接口也返回了数据,说明本次低代码平台第三方接口跨域问题解决。
总结
有时候,前端很无奈,跨域其实是一个非常小的问题,惯用的做法就是后端设置一下access-control-allow-origin
就可以了,但是由于服务端不愿意加或者服务端统一走的公司网关,自己代码加的不起作用,就需要在网关层加配置,但是网关层可能加起来比较麻烦,最终就不了了之了。
还有一个常用的就是nginx
反向代理,小公司可能还好,找运维加一下就OK
,但是大体量的公司,一般可能找运维处理这些问题会比较麻烦,因为可能都不知道运维是谁。
所以,本次低代码搭建的过程,觉得这个思路挺好,以后就能彻底解决跨域问题了,也不用去求别人了。