You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React单页应用中调用MS Graph Search API获取SharePoint列表项

在React单页应用中调用Microsoft Graph API获取SharePoint列表项

前置准备

  • 在Azure AD中注册**单页应用(SPA)**类型的应用:
    • 添加与React应用匹配的重定向URI(比如本地开发用http://localhost:3000)
    • 授予Delegated权限:Sites.Read.All(只读)或Sites.ReadWrite.All(读写),并完成权限同意(管理员或用户同意,取决于权限类型)

配置认证(使用MSAL React)

微软官方推荐使用@azure/msal-react和@azure/msal-browser处理SPA的身份验证:

  1. 安装依赖:
npm install @azure/msal-react @azure/msal-browser
  1. 创建认证配置文件(src/authConfig.js):
import { PublicClientApplication } from "@azure/msal-browser";

export const msalConfig = {
  auth: {
    clientId: "你的Azure AD应用ID",
    authority: "https://login.microsoftonline.com/你的租户ID",
    redirectUri: "http://localhost:3000" // 与注册的重定向URI一致
  }
};

export const msalInstance = new PublicClientApplication(msalConfig);
export const graphEndpoint = "https://graph.microsoft.com/v1.0";
export const requiredScopes = ["Sites.Read.All"];
  1. 在根组件中包裹应用(src/App.js):
import { MsalProvider } from "@azure/msal-react";
import { msalInstance } from "./authConfig";
import SharePointListViewer from "./SharePointListViewer";

function App() {
  return (
    <MsalProvider instance={msalInstance}>
      <SharePointListViewer />
    </MsalProvider>
  );
}

export default App;

获取SharePoint列表项(直接调用Graph API)

创建组件SharePointListViewer.js,实现列表项获取逻辑:

import { useEffect, useState } from "react";
import { useMsal } from "@azure/msal-react";
import { requiredScopes, graphEndpoint } from "./authConfig";

const SharePointListViewer = () => {
  const [listItems, setListItems] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const { instance, accounts } = useMsal();

  const fetchListItems = async () => {
    const activeAccount = accounts[0];
    if (!activeAccount) return;

    try {
      // 静默获取访问令牌
      const tokenResponse = await instance.acquireTokenSilent({
        account: activeAccount,
        scopes: requiredScopes
      });

      // 替换为你的站点ID和列表ID
      // 站点ID可以是格式:`{domain}:/{site-path}:/`(例如`contoso.sharepoint.com:/sites/HRPortal:/`)
      const siteIdentifier = "你的站点ID";
      const listId = "你的列表ID";
      
      // 调用Graph API,按需指定要返回的字段
      const apiUrl = `${graphEndpoint}/sites/${siteIdentifier}/lists/${listId}/items?$select=id,Title,Description`;

      const response = await fetch(apiUrl, {
        headers: { Authorization: `Bearer ${tokenResponse.accessToken}` }
      });

      if (!response.ok) throw new Error(`请求失败: ${response.statusText}`);
      
      const data = await response.json();
      setListItems(data.value);
    } catch (error) {
      // 静默获取令牌失败时,弹出登录窗口
      if (error.name === "InteractionRequiredAuthError") {
        instance.acquireTokenPopup({ scopes: requiredScopes });
      } else {
        console.error("获取列表项失败:", error);
      }
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    fetchListItems();
  }, [accounts, instance]);

  if (isLoading) return <div>加载中...</div>;

  return (
    <div>
      <h2>SharePoint列表内容</h2>
      <ul>
        {listItems.map(item => (
          <li key={item.id}>
            <h3>{item.Title}</h3>
            {item.Description && <p>{item.Description}</p>}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default SharePointListViewer;

使用Graph Search API跨站点搜索列表项

如果需要跨多个站点搜索列表项,可以使用Graph Search API:

在SharePointListViewer.js中添加搜索逻辑:

const searchListItems = async (searchKeyword) => {
  const activeAccount = accounts[0];
  if (!activeAccount || !searchKeyword) return;

  try {
    const tokenResponse = await instance.acquireTokenSilent({
      account: activeAccount,
      scopes: requiredScopes
    });

    const searchUrl = `${graphEndpoint}/search/query`;
    const response = await fetch(searchUrl, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${tokenResponse.accessToken}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        requests: [
          {
            entityTypes: ["listItem"],
            query: { queryString: searchKeyword },
            fields: ["id", "Title", "webUrl"],
            from: 0,
            size: 20 // 控制返回结果数量
          }
        ]
      })
    });

    if (!response.ok) throw new Error(`搜索失败: ${response.statusText}`);
    
    const data = await response.json();
    const searchResults = data.value[0].hitsContainers[0].hits.map(hit => hit.resource);
    setListItems(searchResults);
  } catch (error) {
    console.error("搜索列表项失败:", error);
  }
};

关键注意事项

  • 权限配置:确保Azure AD应用的权限已被正确同意,否则会返回403错误
  • 站点/列表ID获取:可以通过Graph API的GET /sites或GET /sites/{domain}:/{site-path}:/lists接口获取,也可从SharePoint列表页面的URL参数中提取ListId
  • CORS设置:在Azure AD应用的"API权限" -> "跨域资源共享(CORS)"中添加React应用的域名(比如http://localhost:3000)
  • 错误处理:务必处理令牌过期、无权限、网络错误等场景,提升用户体验

内容的提问来源于stack exchange,提问作者Sonu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:40:25