开发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参数) - 获取认证令牌(可以从页面的
AuthTokencookie或者全局的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
相关产品推荐
相关产品推荐

