兩種方法,使用 config.backend.timeout = { 瀏覽器:...,伺服器:...}
,或者可以更具體地配置,即基於 Request 粒度,透過將 HTTP_TIMEOUT_CONFIG HttpContextToken 傳遞給 Angular HttpClient 的方法來針對每個具體請求進行配置。
在SSR(Node.js)中,超時處理耗時過長的外部http呼叫是一項尤為重要的改進,因為在Node.js中,與瀏覽器不同,Node.js 執行環境下並沒有預設的外部http呼叫超時時間(瀏覽器通常會在長時間後超時長時間的http呼叫,例如1分鐘)。
這種可配置的超時邏輯現在已經在Spartacus中的 Angular Http攔截器層面上實現。也就是說,在 Spartacus SSR long API timeout
功能釋出之前,客戶可以自己實現類似的邏輯,例如透過自己實現 Angular Http 攔截器來實現。
配置程式碼:
provideConfig({
backend: {
timeout: {
server: 3_000,
browser: 3_000
}
}
})
如何使用代理伺服器製造後臺 API 響應的延時效果
首先Install http-proxy tool:npm install -g http-proxy
然後開發一個 http-proxy.js server file
const httpProxy = require('http-proxy');
const http = require('http');
const proxy = httpProxy.createProxyServer({ secure: false });
const ENDPOINT_FOR_DELAY = 'consenttemplates';
const BACKEND_BASE_URL = 'https://jerry:9002';
const DELAY = 3000; // 手動硬編碼的延時
/** custom predicate, whether we should delay a request */
const shouldDelay = (req) => {
// Note: In browser there are 2 requests: preflight (OPTIONS) and actual request (GET).
const result = req.url.includes(ENDPOINT_FOR_DELAY);
result && console.log({ delay: DELAY, url: req.url, method: req.method });
return result;
};
http
.createServer(function (req, res) {
const forwardRequest = () =>
proxy.web(req, res, { target: BACKEND_BASE_URL });
const delay = shouldDelay(req) ? DELAY : 0;
setTimeout(forwardRequest, delay);
})
.listen(9002);
然後啟動這個代理伺服器:node http-proxy.js
最後在 .env-cmdrc
裡指定環境變數 CX_BASE_URL
:
"dev": {
"CX_BASE_URL": "http://localhost:9002"
},
針對某個具體請求設定 timeout:
import { HTTP_TIMEOUT_CONFIG, HttpTimeoutConfig } from `@spartacus/core`;
/* ... */
return this.httpClient.get('/some/api', {
context: new HttpContext().set(
HTTP_TIMEOUT_CONFIG,
{ server: 15_000 } // value in milliseconds
)
})
當超時真的發生之後,可以在 console 看到下列的警告訊息:
Request to URL '${request.url}' exceeded expected time of ${timeoutValue}ms and was aborted.
總之,對於在 NodeJS 中執行的伺服器端渲染應用程式的穩定性來說,為每個傳出的 http 呼叫設定一個明確的超時時間是至關重要的。 否則,如果後端 API 響應非常慢(或從不響應),伺服器端呈現的應用程式將等待響應很長時間(或永遠)。 在這種情況下,為該應用程式分配的記憶體不會被釋放,這會引起記憶體洩漏問題。