1
0x19921213 2023-02-10 17:30:28 +08:00
> 比较极端的情况是 前端把数据暂存在 localstorage 里面,localstorage 被修改后会有脏数据,这样前端把脏数据发到后端会报 4XX 错误,导致前端永远无法再调通后端接口,除非把 localstorage 清空。
这个是什么意思。 |
2
Chad0000 2023-02-10 17:30:51 +08:00 via iPhone
浏览器的数据库中?
|
3
yanz123 OP 现在测试发现前端如果参数传错了的话,后端会返回 4XX 。 前端的数据是存在 localstorage 里面作为参数,如果参数被修改了,也会导致后端一直返回 4XX 。这样程序还没走到后端就失败了
|
4
zoharSoul 2023-02-10 17:37:20 +08:00
sqlite 不行吗? 我看客户端都是存这个里 一般
|
5
7911364440 2023-02-10 17:38:31 +08:00
cookie ?
|
6
renmu 2023-02-10 17:41:18 +08:00 via Android
你们的接口是经常会挂吗?加个最大重试次数呗
|
7
renmu 2023-02-10 17:42:03 +08:00 via Android
或者后端自己把脏数据洗了
|
8
yanz123 OP 问题的根本在于 前端如果有脏数据了之后前端自己感知不到,只会再次往后端发数据,后端返回 4XX 后,前端发送不成功 继续累积数据。
|
9
darkengine 2023-02-10 17:43:04 +08:00
@zoharSoul sqlite 在 iOS/Android 上用,OP 问的应该是 web 的方案。
可以跟后端协商一个脏数据的 4xx error code 啊,尝试上传的时候返回这个 code 就清掉 localStorage 的数据。 |
10
Freakr 2023-02-10 17:43:36 +08:00
后端一律返回 200 ,解析不了的放另一个表里
|
11
stillsilly 2023-02-10 17:44:08 +08:00
@yanz123
数据格式错误定一个单独的错误码,如果是这个错误码,把 localstorage 里的数据全部清除 |
12
yanz123 OP 接口并不会挂,今天测试的时候偶然发现,接口传错数据了会造成前端数据累积,引发的这个联想。
4XX 的时候,逻辑并没有进到后端,后端无法处理。 |
13
Chad0000 2023-02-10 17:45:59 +08:00 via iPhone
@darkengine 浏览器也就是 web 有数据库。
|
14
implion 2023-02-10 17:46:16 +08:00
不能在发送给服务器之前,从 localStorage 取出数据,然后校验下数据,再上传吗?你无法区分数据是不是脏数据?一般被服务器认为是脏数据,要么是数据格式不对,要么是时间戳不对
|
15
darkengine 2023-02-10 17:47:23 +08:00
@Chad0000 有关键字没,我也学下,我们的产品是全部怼到 localStorage 了。
|
16
implion 2023-02-10 17:48:02 +08:00
应该不是逻辑没进入后端,是后端用了数据格式校验的框架,在数据格式校验的时候就不通过,就给 throw 了
|
17
hqmJoker 2023-02-10 17:48:52 +08:00
这不是调用完就清数据就行?(不管成不成功)
因为如果本来数据有问题,还保存的话下次也会有问题。如果没有问题,那么这批数据就没用了,所以都得清掉,除非后端能返回更多的信息,根据返回信息清理旧数据。 |
18
llsquaer 2023-02-10 17:51:28 +08:00
后端数据错误或者不合理 返回 4xx 本来就合理
按正常逻辑怎么来的脏数据呢? 不妨前端优化下前端逻辑避免脏数据. 后端严卡数据进入. |
19
yanz123 OP 全部粗暴丢弃的话有一个弊端,就是可能不是数据脏了导致前端没有把数据发给后端,可能是后端挂了导致的,这样后端再重启后,前端其实是可以把这些数据传到后端的
|
20
dingjs 2023-02-10 17:53:23 +08:00
|
21
darkengine 2023-02-10 17:54:04 +08:00
|
22
LavaC 2023-02-10 17:55:14 +08:00
浏览器有自带的 indexDB 数据库
|
23
yaphets666 2023-02-10 17:56:05 +08:00
17 楼说的应该没问题,调接口之前,清空 localStorage 相关字段,调接口后如果失败了,再把数据存回去。
|
24
ccagml 2023-02-10 17:56:18 +08:00 via Android
一定需要 20 条才能发?
如果错了就把 20 分成 10,10 两组发,其中有错了在把 10 分成 5,5 发呢 如果脏数据返回 400+ 后端挂了应该会返回 500+ |
25
nekochyan 2023-02-10 18:05:28 +08:00
如果有脏数据为什么后端不把脏数据是哪些返回给前端,这样前端清掉这些脏数据不就行了吗
|
26
a13761839322 2023-02-10 18:05:41 +08:00
数据错误是什么原因?代码原因还是业务原因,代码原因保证自己的健壮即可,业务原因就返回对应错误 ,修正数据(剔除错误条目)后 retry
使用 localstorage 出于什么考虑,多 tab 的共享吗?简单点可以直接放内存,内存也没你想的那么脆弱,还方便管理 |
27
darkengine 2023-02-10 18:07:19 +08:00
@a13761839322 估计有些埋点数据吧,放内存里关掉 tab 就没了。
|
28
xwayway 2023-02-10 18:08:07 +08:00 via iPhone
或许这些数据并不重要,重要就不会采取这种方式来传输了,既然不重要,默认允许可以失败,即脏数据可以丢弃
|
29
yanz123 OP 是的 我们有埋点数据 关掉浏览器后数据还得在
|
30
tool2d 2023-02-10 18:12:24 +08:00
用 indexdb 很合适,就是 API 是异步,而 localstorage 是同步,需要改改代码。
|
31
libook 2023-02-10 18:26:11 +08:00
后端区分一下故障类型,前端根据后端返回的故障类型来选择策略:
数据格式错误,清除 localstorage ; 其他错误,稍后重试。 |
32
seth19960929 2023-02-10 18:26:52 +08:00
参考别家的系统看看. 用 localstorage 模拟队列.
1. 0~100 先从 队列取到 0~20, 发送成功再删除队头 20 条, 发送失败放到队尾. 2. 限制最大条数, 比如 1W 条, 超过之后老的删除掉.(取决于你的业务是否能删除) 3. 让你们服务端应该不要返回错误, 永远存储数据, 后端自己做数据清洗 |
33
gam2046 2023-02-10 18:27:07 +08:00
@yanz123 #19 就是#17 说的。后端返回 4xx 状态码就是数据本身的问题,无脑删掉就行了,留着,下次请求也是失败。如果是服务端挂了,返回的是 5xx 状态,或者直接是请求不通,那就留着下次再用呀。
|
34
otakustay 2023-02-10 18:53:07 +08:00
前端也做个 FIFO 队列呗,实在不行了该丢就丢
|
35
DrakeXiang 2023-02-10 19:02:05 +08:00
记录行为那就是日志,日志怎么会需要修改和校验?如果后端给不出哪调出错那就只能如楼上所说,要么自己把出错的试出来去掉,要么就整块丢掉,大小自己掌握
|
36
duan602728596 2023-02-10 19:03:29 +08:00
IndexedDB 啊,前端也是有数据库的。
localstorage 同步,还是存的字符串。不适合这个业务场景。 每条数据可以对应唯一 ID ,重复的数据传到后端也不处理。 |
37
KisekiRemi 2023-02-10 19:07:08 +08:00
indexDB 啊,定 key 判断,或者加入时间区间,在某个时间区间报错就设定规则删除,具体逻辑看具体需求设置
|
38
wonderl17 2023-02-10 19:11:58 +08:00
前端校验数据就行了呀,后端那边也可以校验后丢弃不报 4xx 呀
|
39
chairuosen 2023-02-10 19:14:36 +08:00
让后端改
|
40
Bijiabo 2023-02-10 19:54:41 +08:00
看起来这个设计有些问题。如果后端一直报错,或者后端用于接收错误的接口有一定概率报错,就比较崩溃了。
如果我来做这个选择,我可能会考虑区别于当前的后端服务,使用一个单独的服务来收集数据。一些用户行为打点的服务,也有错误收集功能。 |
41
a13761839322 2023-02-10 19:57:46 +08:00
@yanz123 埋点感觉也没必要这种 积累上传...直接 img ping 的形式上报就行了
不行就是 indexDB + rxjs 定时 observable 和数量 合并,还可以用 web worker 不影响主线程(不过这样有点过度设计,大多数产品也没多大并发,直接一次次往后台扔得了 |
42
Finnn 2023-02-10 21:08:14 +08:00
Google analysis 的数据就是比较智能上报的, 数据出问题不能靠前端, 数据都到后台了后端也不处理的吗
|
44
adoal 2023-02-10 21:24:35 +08:00
后端返回 4 了前端还“自己感知不到”?正常设计里难道 4 不是表示后端正常、前端传的数据有问题?“如果后端接口报错了,前端就会把这些记录继续暂存在前端”,难道你们的设计是后端接口返回任何非 2/3 的代码前端都当成是后端出问题了?
|
45
darlinghsu 2023-02-10 21:25:57 +08:00
我们是统一收集发送,后端去存储,至于脏数据的问题自然有数据团队去做清洗和处理(也会和我们确认,写清理规则的时候
如果明确错误数据需要改进的,就再反馈回来 优化埋点。 |
46
wellerman 2023-02-10 22:15:03 +08:00
都 4XX 了,不就是前端问题了吗。后端再返回具体的错误码,前端根据具体的错误码去处理数据不就行了。
|
47
joesonw 2023-02-10 22:41:32 +08:00 via iPhone
4xx 丢弃,5xx 才保存呗。
|
48
ArcherD 2023-02-10 22:55:25 +08:00
用 graphql 和 relay 的话框架里面对于这些问题都覆盖了 参见 Fetch Policies ,Error States with ErrorBoundaries
后台不用 graphql 的话 就另说 |
49
litchinn 2023-02-11 09:35:33 +08:00
@darkengine 现在有 wasm ,浏览器都可以跑 postgresql
|
50
gausszhou 2023-02-11 19:15:08 +08:00
让后端改成只要接收到埋点数据就返回 200
|
51
gausszhou 2023-02-11 19:18:35 +08:00
另外无限积累数据可不行
1. 存储空间有限,localStorage 上限为 5MB 2. 随着数据变多,localStorage 读写和 JSON 序列化 会占用较多的 CPU 时间,影响用户网页的正常业务和性能指标。 |
52
paopjian 2023-02-11 21:48:10 +08:00
sqlite 现在支持 wasm,其实没必要累计记录数据吧,重要数据肯定 post 发了,不重要的日志扔给 mq 管他到底收没收到
|
53
MMMMMMMMMMMMMMMM 2023-02-12 14:54:39 +08:00
看起来客服平台应该是第三方的了
建议开个 ws ,这边发一条,直接同步发送到这个 ws 里去 如果担心后端 IO 压力的话,可以在后端处理接到多少条推送之后再统一插入数据库 |