Javascript从Dynamics Online发布到外部网站

[英]Javascript post to external site from Dynamics Online

I've been trying for most of the day to post data to an external WebAPI endpoint when the OnSave event is triggered from a Microsoft Dynamics 365 form. Unfortunately, despite an extraordinary amount of research, I haven't been able to successfully post the data.

当从Microsoft Dynamics 365表单触发OnSave事件时,我一直在尝试将数据发布到外部WebAPI端点。不幸的是,尽管进行了大量研究,但我还是无法成功发布数据。

Having spent about an hour stumbling around getting the javascript library referenced in the right form, I tried reference jQuery from within my script, and trying to use $.ajax to trigger the post, using a declared alias. Here's a redacted version of the code:

花了大约一个小时磕磕绊绊地想要以正确的形式引用javascript库,我尝试从我的脚本中引用jQuery,并尝试使用$ .ajax来触发帖子,使用声明的别名。这是代码的编辑版本:

function UpdateSupplierStatus()
   var $jQ = jQuery.noConflict();

   var MembershipNumber ="membershipnumber").getValue();
var StatusCode ="statuscode").getText();

    url: '', 
    type: 'POST',
    data: {
            'membershipNumber' : MembershipNumber,
            'statusCode' : StatusCode
    datatype: 'json',
    success: function() {},
    error: alert("There was an error performing the update.")

No matter what I try, it seems that as soon as I try to execute the post, I fall straight into the 'error' clause. I've run Fiddler in the background whilst debugging the script using Internet Explorer, and there's no attempt made to hit the endpoint specified - it simply doesn't try, just errors.

无论我尝试什么,似乎只要我尝试执行帖子,我就会直接进入“错误”条款。我在后台运行Fiddler,同时使用Internet Explorer调试脚本,并且没有尝试命中指定的端点 - 它只是不尝试,只是错误。

I did some research, and came across a number of articles like this that suggest using XmlHttpRequest instead of trying to poke posts around the internet using jQuery, and so I tried using this instead:


function UpdateSupplierStatus()
var MembershipNumber ="membershipnumber").getValue();
var StatusCode ="statuscode").getText();

var Query = "?membershipNumber=" + MembershipNumber + "&statusCode=" + StatusCode;
var URL = "";

var req = new XMLHttpRequest();"POST", URL + Query, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");


Again, if I debug this it's unsuccessful, however this time it seems that the offending line is '' - from what I've read, the suggestion is that I can't use XmlHttpRequest to make requests to resources outside of the hosts domain. The problem here is that CRM is hosted and the related website is obviously elsewhere. There is a question around this problem that describes the 'fix' as requiring users to alter their security settings, but frankly I find this to be madness - I cannot, and will not, require my customers to alter their security settings to allow this to work.

再次,如果我调试它不成功,但这次似乎违规行是'' - 从我读过的,我的建议是我不能使用XmlHttpRequest来发出请求主机域之外的资源。这里的问题是CRM托管,相关网站显然是其他地方。有一个问题围绕这个问题描述'修复'要求用户改变他们的安全设置,但坦率地说,我发现这个疯狂 - 我不能,也不会,要求我的客户改变他们的安全设置以使其工作。

What am I missing here? Is it really this difficult to post data to an external site using Dynamics 365, or is there some process that I'm missing that facilitates exactly this?

我在这里想念的是什么?使用Dynamics 365将数据发布到外部站点真的很难吗,或者是否有一些我缺少的过程正是如此?

Edit So I've tried testing this with a different browser and I get further using the XmlHttpRequest method than I was getting with the $.ajax method. However, I've not self-signed localhost, and our staging environment has no SSL certificate, and so I can't supply the content via HTTPS. I now have two issues:

编辑所以我尝试使用不同的浏览器进行测试,然后我使用XmlHttpRequest方法进一步使用$ .ajax方法。但是,我没有自签名localhost,我们的暂存环境没有SSL证书,因此我无法通过HTTPS提供内容。我现在有两个问题:

I can't require people to not use IE
I can't easily get HTTPS working in either my development environment, or in my staging environment

I'm starting to feel more and more like this isn't a problem with Dynamics!


2 个解决方案



This is not an issue related to Dynamics 365 but related to CORS:

这不是与Dynamics 365相关但与CORS相关的问题:

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain.


The Cross-Origin Resource Sharing (CORS) mechanism gives web servers cross-domain access controls, which enable secure cross-domain data transfers. Modern browsers use CORS in an API container - such as XMLHttpRequest or Fetch - to mitigate risks of cross-origin HTTP requests.


More information...


You will find a lot of examples about different scenarios and different ways to perform a cross-domain request (in the previous link you will find a lot of these information).


The following it's a "simple request", which I think it will work in your scenario (the allowed methods are GET, HEAD and POST), and you can test it directly from CRM if you want (I've done it without problems as you can see in the screenshot that I've also uploaded):


function callOtherDomain() {
  var req = new XMLHttpRequest();
  var url = '';'GET', url, true);

  req.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {


enter image description here

This "simple request" will use CORS headers to handle the privileges:


enter image description here

As you can see, the server ( in your scenario) also has to be configured to explicitly allow cross-domain requests. You can see a very detailed tutorial to enable this option in the following MSDN article (assuming that you're using WebAPI).




Your jQuery ajax call is not working because you are not passing a function definition to your error handler, but rather executing some code (alert...) directly.

您的jQuery ajax调用无法正常工作,因为您没有将函数定义传递给错误处理程序,而是直接执行某些代码(alert ...)。

Try wrapping the code in an inline function definition like this:


 url: '', 
 type: 'POST',
 data: {
        'membershipNumber' : MembershipNumber,
        'statusCode' : StatusCode
 datatype: 'json',
 success: function() {},
 error: function() { alert("There was an error performing the update."); }

Also, add this line in the beginning of your code (after the .noConflict):


$ = true;

Furthermore, please make sure your webservice accepts Cross Origin Requests.To do so in your Web API project, make the following changes:

此外,请确保您的Web服务接受Cross Origin Requests。要在Web API项目中执行此操作,请进行以下更改:

  • Install the Nuget Package Microsoft.AspNet.WebApi.Cors
  • 安装Nuget包Microsoft.AspNet.WebApi.Cors
  • Add the following attribute to your class:


    [EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "")] public class MembershipAPIController : ApiController


  • Add the following in your web.config under the tag:


    <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="*" /> </customHeaders> <httpProtocol>

The last step is needed to include both headers in the response. When these headers are missing, the response will be blocked by the browser. I'm pretty sure you're missing the xml-tags in your web.config.




粤ICP备14056181号  © 2014-2021