Open
Description
问题描述
发送埋点请求时,判断如果支持 sendBeacon,就使用 sendBeacon,不支持就使用 Fetch 或 Ajax。使用Fetch请求封装如下
// 封装的请求方法
export function Fetch(url: string, method = "POST", data: any) {
return new Promise((resolve, reject) => {
let options = {};
if (method !== "GET") {
options = {
headers: {
"Content-Type": "application/json",
},
body: data
};
}
fetch(url, {
mode: "cors", // no-cors, cors, *same-origin
method,
...options,
// credentials: 'include',
})
.then((res) => {
return res.json();
})
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
然后代码里是这么判断的
const finalData = JSON.stringify({data: '哈哈哈'})
if (typeof navigator.sendBeacon !== "undefined") {
// 使用 sendBeacon 上报, 参考: https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/sendBeacon
window.navigator.sendBeacon(reportUrl, finalData);
} else if (typeof fetch !== "undefined") {
Fetch(`reportUrl`, "post", finalData);
}
然后请求后,发现使用 Fetch 是可以正常请求的,因为 Content-Type = application/json,所以是复杂请求,会有一个 option 请求。
但是使用 sendBeacon 会报错 cors
问题排查
然后看了下后端的设置
import cors from "@koa/cors"
app.use(cors({origin: *}))
解决方案:
- 不能设置 Access-Control-Allow-Origin 为 ”*“
- 需要设置 Access-Control-Allow-Credentials: true
import cors from "@koa/cors"
app.use(cors({Credentials: true}))
参考文档
Metadata
Metadata
Assignees
Labels
No labels