I am working on a web app that sends some data to a website. The website updates the data to its database and returns a json array that replaces my webapp page. I am using ajax for making the query. I need to know how to prevent the overwriting of my webpage. The server is not mine so there is possibly a same origin policy problem.
I have checked the xmlhttp.readystate and xmlhttp.status, they are 4 and 0 respectively. According to some posts on stackoverflow the 0 status occurs due to the origin policy but I couldn't get a solution for this because usually the people with this problem had access to changes on the server side programming.
I want to read the json and extract values for my app but if I use the xmlhttp.responseText the server returns a blank string.
Any help is much appreciated.
Thanks
My code:
function sendAndReceive() {
var xmlhttp;
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
document.getElementById("postevent").innerHTML = "state changed";
document.getElementById("postevent").innerHTML = "" + xmlhttp.readyState + " " + xmlhttp.status;
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("postevent").innerHTML = "success response";
document.getElementById("postevent").innerHTML = "this is it" + xmlhttp.responseText;
}
}
var url = "http://simple.ap.ernet.in/api/home/resource.php/resource/node?";
url += "key=" + document.getElementById("key").value + "&";
url += "datasetId=" + document.getElementById("datasetId").value + "&";
url += "localId=" + document.getElementById("localId").value + "&";
url += "nodeName=" + document.getElementById("nodeName").value + "&";
url += "nodeDesc=" + document.getElementById("nodeDesc").value + "&";
url += "lat=" + document.getElementById("lat").value + "&";
url += "long=" + document.getElementById("long").value;
document.getElementById("postevent").innerHTML = url;
xmlhttp.open("POST", url, true);
xmlhttp.send();
}
The only known workaround is to let the browser think there is only one origin. The easiest is to put a proxy on your own server relaying to the other server. If your own server is in Apache, you may use mod_proxy (see this question).
But note that if the other server doesn't allow cross-origin requests, it's probably against its policy to do that. And if it's a big server, it may very well detect it and ban your server's IP.
Related
I am trying to do http GET request for a MS flow using XMLHttpRequest in java script but getting the above error.
I know this is because of the url.Can anyone help me what is the exact issue with my url.
var finalurl = "https://prod4-30.centralindia.logic.azure.com:443/workflows/ed30ad9219a940fa8e5af317cf697e4c/triggers/manual/paths/invoke?api-version=2016-06-01&sp=/triggers/manual/run&sv=1.0&sig=ctQe3OAscgTfzDgji9gS_B43lvHEV4JP-hGdaxu46wg";
function DohttpRequest(greeting) {
alert(greeting);
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET', '" + finalurl + "', false);
xmlHttp.send(null);
var jsonResponse = JSON.parse(xmlHttp.responseText);
console.log(jsonResponse);
alert(xmlHttp.responseText);
}
I am doing the GET request in sharePoint using the custom action. The definition of the custom action with CommandAction is as below
UserCustomAction SPToDBAction = collUserCustomAction.Add();
SPToDBAction.Location = "CommandUI.Ribbon.ListView";
SPToDBAction.Sequence = 10001;
SPToDBAction.Title = "SPToDBAction";
string location = "<CommandUIDefinition Location=\"Ribbon.ListItem.Actions.Controls._children\">";
SPToDBAction.CommandUIExtension = #"<CommandUIExtension><CommandUIDefinitions>"
+ location
+ "<Button Id=\"InvokeAction.Button\" TemplateAlias=\"o1\" Command=\"EditFormButtonCommand\" CommandType=\"General\" LabelText=\"Sync SP To DB\" Image32by32=\"data:image/png;base64,iVB= \" />"
+ "</CommandUIDefinition>"
+ "</CommandUIDefinitions>"
+ "<CommandUIHandlers>"
//+ "<CommandUIHandler Command =\"EditFormButtonCommand\" CommandAction = \"javascript:alert('Custom List ECB custom Action')\" />"
+ "<CommandUIHandler Command =\"EditFormButtonCommand\" CommandAction = \"javascript:DohttpRequest('Are you sure to sync the Items from Sharepoint to Database'); function DohttpRequest(greeting){ alert(greeting); var xmlHttp = new XMLHttpRequest(); xmlHttp.open( 'GET', '" + finalurl + "', true ); xmlHttp.send( null ); var jsonResponse = JSON.parse( xmlHttp.responseText); console.log(jsonResponse); alert( xmlHttp.responseText);}\" />"
+ "</CommandUIHandlers></CommandUIExtension>";
SPToDBAction.Update();
Synchronous XMLHttpRequest (async = false) is not recommended because the JavaScript will stop executing until the server response is ready. If the server is busy or slow, the application will hang or stop.
With asynchronous request you need to wait for server answer, for do that you need to work with XMLHttpRequest onreadystatechange property, so in the end your function code will look like this...
function DohttpRequest(greeting) {
alert(greeting);
let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
let jsonResponse = JSON.parse(this.responseText);
console.log(jsonResponse);
alert(this.responseText);
}
};
xmlHttp.open('GET', '" + finalurl + "', true);
xmlHttp.send();
}
Hope it helps...
I need to connect to our corporate PWA. This is the code I'm using:
// var endpointUrl = 'https://<companySite>.sharepoint.com/sites/pwa/_api/web/lists';
var endpointUrl = 'https://<companySite>.sharepoint.com/sites/pwa/_api/ProjectData/Projects?$select=ProjectName';
var xhr = new XMLHttpRequest();
xhr.open("GET", endpointUrl);
// The APIs require an OAuth access token in the Authorization header, formatted like this: 'Authorization: Bearer <token>'.
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader("Accept", "application/json");
$("#header").html("Requesting: " + endpointUrl);
// Process the response from the API.
xhr.onload = function () {
if (xhr.status == 200) {
var formattedResponse = JSON.stringify(JSON.parse(xhr.response), undefined, 2);
$("#results").html("<pre>" + formattedResponse + "</pre>");
} else {
$("#results").html("HTTP " + xhr.status + "<br>" + xhr.response);
}
}
// Make request.
xhr.send();
I've tried also a few different ways, all using Bearer token.
The problem is that this code works for accessing https://<companySite>.sharepoint.com/sites/pwa/_api/web/lists but doesn't for https://<companySite>.sharepoint.com/sites/pwa/_api/ProjectData/Projects?$select=ProjectName
For the latter it returns:
{"odata.error":{"code":"20010, Microsoft.ProjectServer.PJClientCallableException","message":{"lang":"en-US","value":"GeneralSecurityAccessDenied"}}}
What could be the possible problem?
I know that my token is correct, as it works for accessing */web/lists. I also know that the url is correct, as I can open it in my browser (providing that I'm logged in into sharepoint)
You need to use a FormDigestValue.
Make a GET call to .../_api/contextinfo and store the value of 'FormDigestValue'. Then for all your other calls, add a header of X-RequestDigest: <FormDigestValue>
Scenario:
I would like to invoke an already defined workflow or a custom action from a web page which is located outside the CRM Dynamics context. (Let's say MS CRM 2011-2013-2015-2016 and 365)
My solution:
My idea would be about defining a kind of controller page into the CRM context accessible from the web and execute the rest call within that page (through javascript).
This page will be able to read input parameters and execute the right rest call.
Does it make sense? Could you suggest a better implementation?
Thanks in advance!
If you have the resources, you can setup a service utilizing the following methods and then ajax it.
private static void ExecuteWorkflow(Guid workflowId, Guid entityId)
{
try
{
string url = ConfigurationManager.ConnectionStrings["crm"].ConnectionString;
ClientCredentials cc = new ClientCredentials();
cc.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
OrganizationServiceProxy _service = new OrganizationServiceProxy(new Uri(url), null, cc, null);
ExecuteWorkflowRequest request = new ExecuteWorkflowRequest()
{
WorkflowId = workflowId,
EntityId = entityId
};
ExecuteWorkflowResponse r = (ExecuteWorkflowResponse)_service.Execute(request);
_service.Dispose();
}
catch (Exception ex)
{
//Handle Exception
}
}
If you're unable to have the service on the same domain as the CRM server, you should be able to impersonate.
cc.Windows.ClientCredential.Domain = "DOMAIN";
cc.Windows.ClientCredential.Password = "PASSWORD";
cc.Windows.ClientCredential.UserName = "USERNAME";
You can find more details here.
https://msdn.microsoft.com/en-us/library/microsoft.crm.sdk.messages.executeworkflowrequest.aspx
You can invoke a workflow in a js like this:
You can query the workflowId by its name and the type definition.
var entityId = // The GUID of the entity
var workflowId = // The GUID of the workflow
var url = // Your organization root
var orgServicePath = "/XRMServices/2011/Organization.svc/web";
url = url + orgServicePath;
var request;
request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<s:Body>" +
"<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
"<request i:type=\"b:ExecuteWorkflowRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">" +
"<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">" +
"<a:KeyValuePairOfstringanyType>" +
"<c:key>EntityId</c:key>" +
"<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + entityId + "</c:value>" +
"</a:KeyValuePairOfstringanyType>" +
"<a:KeyValuePairOfstringanyType>" +
"<c:key>WorkflowId</c:key>" +
"<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + workflowId + "</c:value>" +
"</a:KeyValuePairOfstringanyType>" +
"</a:Parameters>" +
"<a:RequestId i:nil=\"true\" />" +
"<a:RequestName>ExecuteWorkflow</a:RequestName>" +
"</request>" +
"</Execute>" +
"</s:Body>" +
"</s:Envelope>";
var req = new XMLHttpRequest();
req.open("POST", url, false);
// Responses will return XML. It isn't possible to return JSON.
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
req.send(request);
If the request.status is 200 the request was succesfull. This was tested on an CRM2011 enviroment.
I recommend you to create a WCF rest or web api, reference the IOrganizationService and from that use the operation of the CRM service. It is better to call a intermediate WCF than the IOrganizationService directly.
I am having difficulties getting access to the values that I am sending to an ASP file from an HTML file. I am attempting to use AJAX POST method to send 3 values to a database and insert them, but to no avail.
Here is the .html code to send the values:
// Builds AJAX request and sends it to ASP page
function sendInfo(x,y,z){
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else{
// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open("POST","UpdateAJAX.asp",true);
xmlhttp.send("addy="+(x)+
"&lat="+(y)+
"&lng="+(z));
}
// Checks the ready state of the sent response
function stateChanged() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
else {
document.getElementById("txtHint").innerHTML="Error with ready state: " + xmlhttp.readyState + " and status: " + xmlhttp.status;
}
}
And here is the 'UpdateAJAX.asp' code:
<%
conn = Server.CreateObject("ADODB.Connection");
conn.Open("DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" + Server.MapPath("Project.mdb"));
' var addy = Request.QueryString("addy");'
' var lat = Request.QueryString("lat");'
' var lng = Request.QueryString("lng");'
var addy = Request.Form("addy");
var lat = Request.Form("lat");
var lng = Request.Form("lng");
var sql="INSERT INTO Location_Info (Address,Latitude,Longitude)"
sql= sql + " VALUES "
sql= sql + "('" + addy + "',"
sql= sql + "'" + lat + "',"
sql= sql + "'" + lng + "')"
Response.Write(sql);
rs = conn.Execute(sql);
Response.Write("Your record has been placed into the database.");
conn.Close();
%>
I have tried both the Request.Form and Request.QueryString methods to retrieve the values from the send, but nothing gets returned. When I use Firefox Firebug to debug the code, this is what is being sent:
'addy=1232 Randall Avenue, Hammond, LA 70403, USA&lat=30.4545509&lng=-90.49790769999998'
It doesn't parse it into the individual variables either way I try and only returns error status of 500, which I have also debugged to mean:
'Data type mismatch in criteria expression.'
When attempting to send the sql statement, as the values are all undefined.
If someone can provide any advice as to how to get the values into the variables, it would be greatly appreciated.
You need to set the Content-Type header of your http request to application/x-www-form-urlencoded. Before you call xmlhttp.send(...), add this line:
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
As I am new with json can you guys please help me out? My data file is at this url - http://www.thedailystar.net/json/category
Now I want to show it in the following format:
<ul id="smenu">
<li></li>
</ul>
So, how can I get the request to get data from the url and run a loop to print it out? I have tried this code but nothing happened. Thanks in advance :)
var xmlhttp = new XMLHttpRequest();
var url = "http://www.thedailystar.net/json/category";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
myFunction(myArr);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(arr) {
var out = "";
var i;
for (i = 0; i < arr.length; i++) {
out += '<li href="' + arr[i].name + '">' +
arr[i].display + '</li><br>';
}
document.getElementById("smenu").innerHTML = out;
}
If your JavaScript is not running on thedailystar.net domain it will be a cross domain request. If this is the case, you will need to enable CORS on your resource server (http://www.thedailystar.net/json/category).
Most of the time, to enable CORS, the server needs to return the following header in its response:
Access-Control-Allow-Origin: *
More information on CORS: http://enable-cors.org/server.html
Your data at the URL provided contains an object with a property named category whit the value being an array. This array is what I suspect you are expecting to parse.
So, only change the call ty myFunction from:
myFunction(myArr);
to:
myFunction(myArr.category);