在选项卡\浏览器关闭时,我需要将数据发送到服务器。我发现this answer (基于 this blog )建议使用 sendBeacon
。 Here显示了如何准备数据才能通过 Ajax 将数据发送到服务器。我重复了答案中的结构:
window.addEventListener('unload', this.sendDataToServer, false)
sendDataToServer () {
myData = JSON.stringify({
'mutation': `mutation EmailAuth($email: String!, $password: String!) {
getOrCreateUser(email: $email, password: $password) {
token
}
}
`,
'variables': {email: '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d6a2b3a5a296a2b3a5a2f8b8b3a2" rel="noreferrer noopener nofollow">[email protected]</a>', password: 'Test'}
})
navigator.sendBeacon('http://localhost:8000/graphql', myData)
}
在本例中,Django 显示:"POST/graphql HTTP/1.1"400 53
我还在互联网上找到了带有 Blob
的版本:
window.addEventListener('unload', this.sendDataToServer, false)
sendDataToServer () {
let headers = {
type: 'application/json'
}
let myBlob = new Blob([JSON.stringify({
'mutation': `mutation EmailAuth($email: String!, $password: String!) {
getOrCreateUser(email: $email, password: $password) {
token
}
}
`,
'variables': {email: '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1763726463576372646339797263" rel="noreferrer noopener nofollow">[email protected]</a>', password: 'Test'}
})], headers)
navigator.sendBeacon('http://localhost:8000/graphql', myBlob)
}
但在这种情况下,Django 根本没有任何反应。
如何将前端的数据包装成GraphQL格式,并以服务器端可以接受的方式放入sendBeacon
中?
最佳答案
在使用按钮而不是unload
的帮助下找到了Blob
不起作用的原因。问题出在 chrome 浏览器上。控制台显示:未捕获的 DOMException:无法在“Navigator”上执行“sendBeacon”:sendBeacon() 的 Blob 类型不是 Content-Type 请求 header 的任何 CORS 安全列表值,该 Blob 被暂时禁用。有关详细信息,请参阅 http://crbug.com/490015。
Django 正在等待 application/json
类型的请求,根据link from error不安全。
对于 Firefox,可以使用 Django 的包 corsheaders
并将 CORS_ALLOW_CREDENTIALS = True
添加到设置中来修复此问题。
关于javascript - 有没有办法使用 'unload\navigator.sendBeacon' + 'GraphQL' 将数据发送到服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49414923/