Navigator.sendBeacon无法与授权标头一起使用

时间:2020-02-19 07:22:54

标签: asynchronous-postback sendbeacon

最近,Chrome在页面卸载或beforeunload事件https://www.chromestatus.com/feature/4664843055398912上停止了对syncnos xmlhttprequest的支持

我尝试使用此解决方案Perform an asynchronous service get when closing browser window / tab with Angular,但似乎无法在最新的chrome版本中使用

现在我正在像这样使用navigator.sendbeacon api

let headers = {
       type: 'application/json; charset=utf-8',
       'authorization': `bearer ${token}`
  }
   let blob = new blob([json.stringify({a:"9"})], headers);

    navigator.sendbeacon(uri, blob);

Api抛出401,因此授权似乎无效, 除了navigator.sendBeacon

还有其他选择吗?

1 个答案:

答案 0 :(得分:2)

在撰写本文时,没有。由于用户的UX错误(用户关闭标签并发出XHR同步请求,浏览器将挂起),Chrome(可能还有其他浏览器早于以后)将不允许XHR同步。

虽然有一些解决方法,但是每个都有其缺点

  1. 使用新的(和实验性的)sendBeacon API-# Override when we are running with the data migrate gem (which we do in prod) # https://github.com/ilyakatz/data-migrate/blob/4db2dba7d53e73cac06aa9bfab136c10aa38367b/tasks/databases.rake#L9 module OverrideDataMigrateMigration def self.included base orig_method = base.method(:run) base.define_singleton_method :run do |*args| puts '-- SET statement_timeout = 600000' ActiveRecord::Base.connection.execute 'SET statement_timeout = 600000' # 10 minutes should suffice, right? orig_method.call *args end end end DataMigrate::DataMigrator.send(:include, OverrideDataMigrateMigration) DataMigrate::SchemaMigration.send(:include, OverrideDataMigrateMigration) 只是“排队”请求,这保证了即使在页面卸载时也会触发该请求。这也不会阻止UX。这样做的一些限制是默认情况下您不能更改请求标头。如果您确实需要添加自定义标头,则必须use a blob,并且标头也应该对CORS友好。而且不适用于较旧的浏览器(看着你,IE)
  2. sendBeacon API + Use fetch()标志-但是,如果您要求标头位于CORS安全列表中,则此方法再次起作用。基本上,如果您的keepalive请求具有某些请求标头,则出于安全原因可以发出预检请求。如果发出了这样的预检请求,则某些浏览器将禁止使用fetch() + fetch()。基本上,您需要使您的请求保持简单以使其正常工作。例如,“例如您不能在此处使用keepalive”。一种解决方法是将数据发送为content-type=application/json并让您的服务器进行相应处理。 有关CORS simple vs preflight requests的更多信息,请参见此处。
  3. Chrome浏览器确实允许使用临时解决方法,但这仅适用于2020年10月。更多信息on that here