javascript fetch api 本身不支持直接配置 saml 策略,因为 saml 是身份验证协议而非 http 请求头。实现“预检”或关联 saml 认证的策略,核心做法是在发起 fetch 请求前,先通过 xmlhttprequest 或另一个 fetch 调用获取 saml token(如 saml assertion),并将其注入到后续请求的 header 中(例如 authorization: bearer <saml_token></saml_token>)。若涉及跨域预检(cors preflight),需确保服务端已正确响应 options 请求并返回必要的 access-control-allow-headers,其中包含承载 saml token 的自定义 header 名称。

CORS 预检请求如何携带 SAML Token 所需的 Header
当使用 fetch 发送非简单请求(如包含自定义 Header)时,浏览器会自动先发一个 OPTIONS 预检请求。SAML Token 通常放在自定义 Header 中,因此必须在预检阶段告知服务器允许该 Header。做法是:在客户端代码中正常设置 Header,服务端需在 OPTIONS 响应中包含 Access-Control-Allow-Headers: X-SAML-Token(假设 Header 名为 X-SAML-Token)。若预检失败,后续带 SAML Token 的实际请求将被浏览器拦截。

const samlToken = 'saml_assertion_value_here';
// 第一步:预检请求(浏览器自动处理,但需服务端配合)
// 第二步:实际请求
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-SAML-Token': samlToken // 自定义 Header,触发预检
},
body: JSON.stringify({ key: 'value' })
})
.then(res => res.json())
.then(data => console.log('Data:', data))
.catch(err => console.error('Fetch failed:', err));
预期结果:若服务端 OPTIONS 响应包含 Access-Control-Allow-Headers: X-SAML-Token,则实际请求成功;否则浏览器报错 No 'Access-Control-Allow-Origin' 或 Request header field X-SAML-Token is not allowed。
立即学习“Java免费学习笔记(深入)”;
SAML Token 获取与注入的完整流程
在实际应用中,SAML Token 并非静态值,而是需要从 Identity Provider (IdP) 动态获取。做法是:先调用 IdP 的端点(如 /saml/login 或 /token)获取 Token,再将 Token 存入内存或 Cookie,随后在 fetch 请求中动态读取并注入。关键点是:Token 获取过程可能涉及重定向或表单提交,需确保最终获得的 Token 格式符合 API 要求(如 Base64 编码的 XML Assertion)。

// 模拟从 IdP 获取 SAML Token
async function getSamlToken() {
const response = await fetch('https://idp.example.com/saml/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
username: 'user@example.com',
password: 'password123'
})
});
if (!response.ok) throw new Error('Failed to get token');
return await response.text(); // 假设返回纯文本 SAML Assertion
}
// 使用 Token 发起业务请求
getSamlToken().then(token => {
fetch('https://api.example.com/secure-data', {
method: 'GET',
headers: { 'X-SAML-Token': token }
}).then(res => res.json()).then(console.log);
});
预期结果:getSamlToken() 返回有效的 SAML Assertion 字符串,随后 fetch 使用该 Token 成功访问受保护资源。若 Token 无效或过期,API 应返回 401 Unauthorized。
如何处理 SAML Token 过期导致的请求失败
当 SAML Token 过期时,fetch 请求会收到 401 或 403 错误。解决策略是:捕获错误后,重新调用 Token 获取函数刷新 Token,并重试原请求。具体做法是在 catch 块中判断状态码,若为 401,则执行 getSamlToken() 获取新 Token,再用新 Token 重试 fetch。需注意避免无限重试循环,可设置最大重试次数。
let retryCount = 0;
const maxRetries = 3;
async function fetchWithRetry(url, options) {
try {
return await fetch(url, options);
} catch (error) {
if (error.status === 401 && retryCount < maxRetries) {
retryCount++;
const newToken = await getSamlToken();
const newOptions = { ...options, headers: { ...options.headers, 'X-SAML-Token': newToken } };
return fetchWithRetry(url, newOptions); // 递归重试
}
throw error; // 超出重试次数或错误类型不符,抛出异常
}
}
预期结果:首次请求因 Token 过期失败,第二次重试使用新 Token 成功。若连续三次均失败(如 IdP 不可用),则最终抛出错误。此机制确保在 Token 有效期内自动维持会话。


















