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