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

开发Chrome扩展访问Dynamics 365 CRM:如何获取formContext或通过其他方式访问?

嘿,这个需求我之前做Chrome扩展对接Dynamics 365 CRM的时候刚好折腾过,给你分享几个靠谱的实现思路:

直接获取formContext的方法

Dynamics 365的formContext(或者旧版的Xrm.Page)是存在页面全局上下文里的,但Chrome扩展的内容脚本和页面上下文是隔离的,没法直接访问。所以得通过注入脚本到页面上下文的方式来获取,再用postMessage把数据传递回内容脚本。

举个具体的代码例子:

// content-script.js(你的Chrome扩展内容脚本)
function injectPageScript() {
  const script = document.createElement('script');
  script.textContent = `
    // 这段代码会运行在Dynamics页面的全局上下文里
    window.addEventListener('message', (event) => {
      if (event.data.type === 'REQUEST_FORM_CONTEXT') {
        // 兼容新旧版本:新版用formContext,旧版用Xrm.Page
        const targetContext = window.formContext || Xrm?.Page;
        // 把formContext的关键方法/数据传递回去(直接传对象会被结构化克隆限制,建议按需提取)
        const contextSnapshot = {
          entityName: targetContext?.data?.entity?.getEntityName(),
          recordId: targetContext?.data?.entity?.getId(),
          getFieldValue: (fieldName) => targetContext?.getAttribute(fieldName)?.getValue()
        };
        window.postMessage({ 
          type: 'FORM_CONTEXT_RESPONSE', 
          data: contextSnapshot 
        }, event.origin);
      }
    });
  `;
  document.head.appendChild(script);
}

// 等待页面加载完成后注入脚本
document.addEventListener('DOMContentLoaded', () => {
  injectPageScript();
  
  // 向页面脚本发送请求获取formContext
  window.addEventListener('message', (event) => {
    // 验证来源,避免恶意消息
    if (event.origin.includes('.crm.dynamics.com') && event.data.type === 'FORM_CONTEXT_RESPONSE') {
      const ctx = event.data.data;
      // 这里就可以操作字段了,比如获取指定字段值
      const myFieldValue = ctx.getFieldValue('new_mytargetfield');
      console.log('目标字段值:', myFieldValue);
    }
  });
  
  window.postMessage({ type: 'REQUEST_FORM_CONTEXT' }, window.location.origin);
});
替代方案:使用Dynamics 365 Web API

如果不想依赖页面的formContext,也可以直接调用Dynamics的Web API来读写数据,步骤大概是这样:

  • 从页面URL解析当前记录的ID和实体类型(比如URL里的id和etc参数)
  • 获取认证令牌(可以从页面的AuthToken cookie或者全局的Xrm对象里提取)
  • 发送Web API请求操作数据

示例代码:

// content-script.js
// 1. 解析页面URL里的记录ID和实体信息
const urlParams = new URLSearchParams(window.location.search);
const recordId = urlParams.get('id')?.replace(/[{()}]/g, '');
const entityTypeCode = urlParams.get('etc');
// 可以提前映射实体类型代码到名称,比如1=account,2=contact
const entityCodeMap = { '1': 'account', '2': 'contact' };
const entityName = entityCodeMap[entityTypeCode];

// 2. 获取认证令牌
function getAuthToken() {
  const cookies = document.cookie.split(';');
  for (const cookie of cookies) {
    const [name, value] = cookie.trim().split('=');
    if (name === 'AuthToken') return decodeURIComponent(value);
  }
  return null;
}

// 3. 调用Web API获取记录字段
const authToken = getAuthToken();
if (authToken && recordId && entityName) {
  fetch(`https://${window.location.host}/api/data/v9.2/${entityName}s(${recordId})`, {
    headers: {
      'Authorization': `Bearer ${authToken}`,
      'OData-MaxVersion': '4.0',
      'OData-Version': '4.0',
      'Accept': 'application/json'
    }
  })
  .then(res => res.json())
  .then(data => {
    console.log('记录数据:', data);
    // 访问目标字段,比如data.new_mytargetfield
  });
}
关键注意事项
  • 版本兼容:Dynamics 365新版本已经逐步废弃Xrm.Page,优先用window.formContext,代码里要做好兼容
  • 扩展权限配置:在manifest.json里必须添加对Dynamics域名的权限,比如:
    {
      "host_permissions": ["https://*.crm.dynamics.com/*"],
      "content_scripts": [
        {
          "matches": ["https://*.crm.dynamics.com/main.aspx?*pagetype=entityrecord*"],
          "js": ["content-script.js"]
        }
      ]
    }
    
  • 安全验证:使用postMessage时一定要验证消息来源(event.origin),避免恶意页面干扰
  • 加载时机:要确保在Dynamics表单完全加载后再执行代码,可以监听DOMContentLoaded或者等待Xrm对象存在

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:22:37