Salesforce Lightning Web Component调用REST API出现401 Unauthorized错误排查
这个问题我之前帮人排查过,核心问题其实出在你代码里的mode: 'no-cors'配置上,咱们一步步拆解解决:
1. 移除mode: 'no-cors'是关键
你设置的mode: 'no-cors'会让浏览器做两件坏事:
- 完全抑制自定义请求头的发送(包括你拼好的
Authorization: Bearer {sessionId}),这直接导致Salesforce服务器无法验证你的身份,返回401 - 返回的response会变成「opaque」类型,你根本无法读取里面的内容,就算请求成功也拿不到数据
因为你的LWC是在Salesforce内部运行的,属于同域请求,完全不需要跨域模式,直接删掉这个配置就行。
2. 安全获取Session ID,别硬编码
你硬写sessionId的方式既不安全,在生产环境也根本没法用(sessionId会过期,而且不同用户的sessionId不一样)。正确的做法是通过Apex安全获取:
第一步:创建Apex控制器
public with sharing class SessionController { @AuraEnabled(cacheable=true) public static String getSessionId() { return UserInfo.getSessionId(); } }
第二步:在LWC中通过@wire获取并调用API
import { wire, api } from 'lwc'; import getSessionId from '@salesforce/apex/SessionController.getSessionId'; export default class AccountQueryComponent extends LightningElement { @wire(getSessionId) sessionId; connectedCallback() { // 等待sessionId加载完成再调用API if (this.sessionId.data) { this.fetchAccounts(this.sessionId.data); } } fetchAccounts(sessionId) { const baseUrl = window.location.origin; const requestUrl = `${baseUrl}/services/data/v50.0/query/?q=SELECT+name+from+Account`; const headers = { "Content-Type": "application/json", "Accept": "application/json", "Authorization": `Bearer ${sessionId}` }; fetch(requestUrl, { method: "GET", redirect: 'follow', headers: headers }) .then(response => { if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } return response.json(); }) .then(result => { console.log('查询结果:', result); // 这里可以处理返回的账户数据 }) .catch(error => { console.error('API调用出错:', error); }); } }
3. 更推荐的方式:用Lightning Data Service或Apex查询
直接调用REST API其实不是Salesforce平台的最佳实践,官方更推荐用以下两种方式,更安全也更符合LWC的设计规范:
方式一:通过Apex查询+@wire导入数据
import { wire, api } from 'lwc'; import getAccountList from '@salesforce/apex/AccountController.getAccountList'; export default class AccountListComponent extends LightningElement { @wire(getAccountList) accounts; // 处理返回的账户数据,比如提取名称列表 get accountNames() { return this.accounts.data ? this.accounts.data.map(acc => acc.Name) : []; } }
对应的Apex控制器:
public with sharing class AccountController { @AuraEnabled(cacheable=true) public static List<Account> getAccountList() { // 可以添加筛选、分页逻辑 return [SELECT Id, Name FROM Account LIMIT 20]; } }
方式二:用Lightning Data Service的getListUi(无需写Apex)
import { wire, api } from 'lwc'; import { getListUi } from 'lightning/uiListApi'; import ACCOUNT_OBJECT from '@salesforce/schema/Account'; export default class AccountListLDSComponent extends LightningElement { @wire(getListUi, { objectApiName: ACCOUNT_OBJECT, listViewApiName: 'AllAccounts', pageSize: 10 }) accountList; get accounts() { return this.accountList.data ? this.accountList.data.records.map(item => item.fields.Name.value) : []; } }
4. 最后检查权限
别忘记确认当前用户有以下权限:
- API Enabled(在用户的权限集/配置文件中开启)
- 读取Account对象的权限
内容的提问来源于stack exchange,提问作者Oubayda Samrouth
相关产品推荐
相关产品推荐

