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

React单页应用中如何正确引用并加载SharePoint的SP.js文件

解决React SPA中加载SP.js并校验SharePoint权限的问题

首先,你遇到的Module not found: Error: Can't resolve '@ms/sp-telemetry'错误,是因为@microsoft/sp-loader是SharePoint Framework (SPFx)专属的加载工具,它依赖SPFx内部的私有包(比如@ms/sp-telemetry),而你的普通React SPA项目并没有这些依赖,所以直接使用它会报错。下面给你两种可行的解决方案:


方案一:动态加载SP脚本(无需SPFx依赖)

对于非SPFx的React应用,最稳妥的方式是通过动态创建<script>标签来加载SharePoint的核心脚本,严格按照依赖顺序加载(因为SP.js依赖前面的几个脚本)。

步骤1:封装脚本加载函数

先写一个通用的Promise封装函数,用于加载单个脚本:

const loadScript = (url) => {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = url;
    script.onload = () => resolve();
    script.onerror = (error) => reject(error);
    document.body.appendChild(script);
  });
};

步骤2:按顺序加载SP相关脚本

在React组件中,使用useEffect(类组件用componentDidMount)来按顺序加载所需脚本:

import { useEffect, useState } from 'react';

const YourComponent = () => {
  const [spScriptsLoaded, setSpScriptsLoaded] = useState(false);
  const [loadError, setLoadError] = useState(null);
  const siteColUrl = window.location.origin; // 或者你的站点集URL

  useEffect(() => {
    const loadSPScripts = async () => {
      try {
        // 严格按顺序加载依赖脚本
        await loadScript(`${siteColUrl}/_layouts/15/init.js`);
        await loadScript(`${siteColUrl}/_layouts/15/MicrosoftAjax.js`);
        await loadScript(`${siteColUrl}/_layouts/15/SP.Runtime.js`);
        await loadScript(`${siteColUrl}/_layouts/15/SP.js`);
        // 如果需要taxonomy功能再加载SP.taxonomy.js
        // await loadScript(`${siteColUrl}/_layouts/15/SP.taxonomy.js`);
        
        setSpScriptsLoaded(true);
      } catch (error) {
        setLoadError(error);
        console.error('加载SP脚本失败:', error);
      }
    };

    loadSPScripts();
  }, []);

  // 脚本加载完成后处理权限校验
  useEffect(() => {
    if (!spScriptsLoaded || loadError) return;

    // 这里调用你的权限校验逻辑
    const checkPermissions = async () => {
      try {
        const response = await fetch(`${siteColUrl}/_api/web/effectivebasepermissions`, {
          headers: { 'Accept': 'application/json;odata=nometadata' }
        });
        const my_effectivePermissions = await response.json();
        
        const my_basePermissions = new SP.BasePermissions();
        my_basePermissions.initPropertiesFromJson(my_effectivePermissions);
        const manageWeb = my_basePermissions.has(SP.PermissionKind.manageWeb);
        console.log('是否拥有管理网站权限:', manageWeb);
      } catch (error) {
        console.error('获取权限失败:', error);
      }
    };

    checkPermissions();
  }, [spScriptsLoaded, loadError, siteColUrl]);

  if (loadError) return <div>加载SP脚本出错:{loadError.message}</div>;
  if (!spScriptsLoaded) return <div>加载中...</div>;

  return <div>权限校验完成</div>;
};

export default YourComponent;

方案二:无需加载SP.js,直接通过权限位计算

如果你只是需要校验特定权限,其实可以跳过加载SP.js,直接通过REST返回的High和Low数值(二进制权限位)来判断。每个SP.PermissionKind对应一个固定的位掩码,你可以直接对比计算:

示例:判断是否拥有ManageWeb权限

SP.PermissionKind.manageWeb对应的掩码是High: 0,Low: 8192(因为该枚举值为14,对应2^(14-1)=8192)。我们可以把返回的High和Low转成BigInt,然后按位与掩码判断:

const checkManageWebPermission = async (siteColUrl) => {
  try {
    const response = await fetch(`${siteColUrl}/_api/web/effectivebasepermissions`, {
      headers: { 'Accept': 'application/json;odata=nometadata' }
    });
    const { High, Low } = await response.json();

    // 转换为BigInt处理大数值
    const userHigh = BigInt(High);
    const userLow = BigInt(Low);
    // ManageWeb权限的掩码
    const manageWebHigh = BigInt(0);
    const manageWebLow = BigInt(8192);

    // 按位与判断是否拥有该权限
    const hasManageWeb = (userHigh & manageWebHigh) === manageWebHigh && (userLow & manageWebLow) === manageWebLow;
    console.log('是否拥有管理网站权限:', hasManageWeb);
    return hasManageWeb;
  } catch (error) {
    console.error('校验权限失败:', error);
    return false;
  }
};

// 在组件中调用
checkManageWebPermission(window.location.origin);

你可以参考SharePoint官方文档获取其他SP.PermissionKind对应的掩码数值,这种方式不需要加载任何SP脚本,更轻量。


关键注意事项

  • 脚本加载顺序必须严格遵循:init.js → MicrosoftAjax.js → SP.Runtime.js → SP.js,否则会出现SP对象未定义的错误。
  • 如果你的SPA部署在子站点,siteColUrl需要指向站点集的根URL(比如https://tenant.sharepoint.com/sites/yoursitecollection),而不是子站点URL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:42:47