beforeUnload時發API. 後端接不到的問題

有個需求是要在重新整理, 關閉分頁, 關閉瀏覽器時, 發送一支API (POST).
目前用@HostListener(‘window:beforeunload’, [’$event’])觸發去寫入localstorage都正確,
然而當我在這事件中, 用平常this.http.post(url, body);的方式(有放在service)呼叫API時,
發生了想不出來為什麼的問題:
當API打自己機器上的後端運作都OK, 但打到放在AWS上的機器就連收都收不到

也因為已上方式不作用, 所以尋求別的方法,
原本找到XMLHttpRequest, 但XMLHttpRequest似乎效能上不太好, 所以後來沒有使用
後來在stackoverflow看到許多文章提到sendBeacon(url, body),
正好sendBeacon是post, 原本歡天喜地以為就要解決之時,
出現401錯誤了… 因為sendBeacon是沒有給人加header的,
但我這專案卻有token要帶, 所以sendBeacon對這個情況下不可行了,
接著找到了這篇文章說可改用fetch就可以解決 https://github.com/w3c/beacon/pull/27
峰迴路轉使用fetch後…卻又發生了我想不出來的問題了:
當我發給自已的後端, 會是400, 關於我帶的參數(Content-Type. body)都沒有帶到的樣子
但我發給AWS的後端時卻是401
以下是我fetch帶的參數
image

請問版眾有沒有遇過 看出蹊蹺可以指點嗎?

打 AWS 的 API 是同一個後端程式嗎? 有怎樣的回傳錯誤訊息嗎?

對是同一支程式,
但因為觸發是在重新整理或關閉分頁
所以網頁並沒有等API回傳東西回來就跳走了
從log去看是401錯

401 是沒有授權的錯誤狀況,前面是有檔什麼特別的驗證嗎?

這支API在同一頁用按按鈕來發送this.http.post(url, body)情況下是正常的

在懷疑用fetch時是token沒帶過去
因為打自己的時候只看的到url中帶的參數,
header. body中帶的東西都沒被抓到
卻不知道fetch 這樣寫是少了什麼?

fetch 的寫法看起來是對的,chrome 的 network 那邊所看到打出去的 request 資訊會是空的嗎?

1個讚

感謝提點, 看來req 資訊有乖乖幫我帶對的資料,
對照Request header的t不一樣
沒成功的fetch的API:
Accept:/
Content-Type: text/plain;charset=UTF-8

有發成功的應該要是
Accept: application/json
Content-Type: application/json

請問fetch 還有其他種帶變數的方式嗎?

網路上看到的一段寫法

(async () => {
  const rawResponse = await fetch('https://httpbin.org/post', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({a: 1, b: 'Textual content'})
  });
  const content = await rawResponse.json();

  console.log(content);
})();

執行的結果

1個讚

剛剛有朋友協助釐清,
發現拿掉這三個參數就能發成功
credentials: ‘include’,
mode: ‘no-cors’,
keepalive: true,
不過我需要keepalive 讓他重新整理或關閉分頁時可以繼續動作
所以目前朝這方面研究看看:face_with_monocle:

只用keepalive會有下面的錯誤
image

1個讚

看起來很像是 ngZone 的問題,讓 fetch 跑在 ngZone 外面看看

 constructor(private zone: NgZone) {
    this.zone.runOutsideAngular(() => {
      // fetch here
    })
  }
1個讚

加了ngZone後error message變了
image

怎麼會是 fetch promise 發生錯誤沒有被 handle 的訊息,是 fetch 失敗嗎?

想換個方式問, 請問若透過httpClient有可以讓他即便重新整理或關閉分頁,
也能順利的讓他被處裡的方式嗎?
類似sendBeacon(); 這種

Angular 我還不知道如何做到跟 sendBeacon 一樣的效果,在研究看看.

的確是fetch 失敗,
找到問題的根本原因了是出在chrome目前對於keepalive有issue
可能要等到M81才能用了QQ 現在是最新的是78
https://bugs.chromium.org/p/chromium/issues/detail?id=835821

看來目前沒有路了 囧
非常感謝Kevin的大力協助!

1個讚