1

Hi I'm working on connecting to an API that is using Layer 7 as an IP authorizer and eGalaxy as a credentials authorizer, when the curl request is sent a line of xml is sent back to me. I'm currently working on localhost, I've implemented the Access-Control-Allow-Origin chrome extension.

My curl request looks as such:

curl https://client-url/eGalaxy.aspx -H 'Content-Type:text/html' --data '<?xml version:"1.0" encoding="UTF-8"?><Envelope><Header><SourceID>0</SourceID><MessageID>131</MessageID><MessageType>Authenticate</MessageType></Header><Body><Authenticate><Username>*username*</Username><Password>*password*</Password><PasswordEncrypted>NO</PasswordEncrypted></Authenticate></Body></Envelope>' --insecure

When I tried to create an ajax request I receive an "Invalid HTTP status code 500" error and "OPTIONS url" which drops down to show:

n.ajaxTransport.k.cors.a.crossDomain.send   @   jquery-2.1.3.js:4
n.extend.ajax   @   jquery-2.1.3.js:4
(anonymous function)    @   VM947:2
InjectedScript._evaluateOn  @   VM899:895
InjectedScript._evaluateAndWrap @   VM899:828
InjectedScript.evaluate @   VM899:694

My ajax code is as follows:

$.ajax({
  url:'https://client-url/eGalaxy.aspx', 
  data:'<?xml version:"1.0" encoding="UTF-8"?><Envelope><Header>
        <SourceID>0</SourceID><MessageID>131</MessageID>
        <MessageType>Authenticate</MessageType></Header><Body>
        <Authenticate><Username>*username*</Username>
        <Password>*password*</Password>
        <PasswordEncrypted>NO</PasswordEncrypted></Authenticate></Body>
        </Envelope>', 
   type:'POST', 
   contentType:'text/xml', 
   dataType:'xml',
   success: function(data){
   },
   error: function(){
   }
 });

Any help with translating into a proper AJAX request would be appreciated!

EDIT: If this makes a difference these are the headers that are returned with the client's xml when the curl is complete(client information deleted)enter image description here

This application will be made into a widget as well, so it will not be running off of a hosting site.

UPDATE 1: I'm using @KevinB's suggestion that the CORS headers were still not properly added.

Here is my updated JS code, copied from this link:

var url = 'https://client-url/eGalaxy.aspx';
var data = '<?xml version="1.0" encoding="UTF-8"?><Envelope><Header><SourceID>1</SourceID><MessageID>131</MessageID><MessageType>Authenticate</MessageType></Header><Body><Authenticate><Username>*username*</Username><Password>*password</Password><PasswordEncrypted>NO</PasswordEncrypted></Authenticate></Body></Envelope>';
var xhr = createCORSRequest('POST', url);
xhr.send(data);
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
}
var xhr = createCORSRequest('GET', url);
if (!xhr) {
throw new Error('CORS not supported');
}

When run with the CORS Chrome extension off I receive an Access-Control-Allow-Origin =! 'null' error. Knowing that CORS needs Access-Control-Allow-Origin header to =! 'null' will this cause problems in the future with making this into a widget that will be put into a Content Manager system?

With it on the origin is set to 'www.evil.com', with the only error in the code being that it says the xhr.send() is an anonymous method. Using breakpoints I can see the xhr in xhr.send() is set to an empty request:

> XMLHttpRequest {response: "", responseText: ""}

Inside the createCORSRequest this line is undefined. I've tested using 'GET' and 'POST' as the method.

xhr.open(method, url, true)

EDIT 2: Using @Fabiano's approach I've changed the web.config for two versions of what I suspect is my server(?). I'm attaching screenshots of what I've gone through the IIS Manager for my system, didn't see a specific webpage so I chose the ASP Net pages changed version 2.0 changed version 4.0 No luck, so far. Decided to use xhr.AppendHeader: did not recognize method did not recognize method I decided to use xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); xhr.RequestHeader The Network tab Headers for eGalaxy.aspx eGalaxy.aspx headers

Christina Leuci
  • 203
  • 2
  • 18
  • 2
    Right off hand, your `curl` request is setting a `Content Type: text/html` header where as your ajax request is setting an `Content Type: text/xml` header. Maybe these two should be aligned? – War10ck Jun 01 '15 at 20:32
  • 3
    your curl request is a ```get``` request is it not? A 500 error is an issue with the server. I am guessing your ```curl``` request is not showing the same error as it is not actually posting anything to the server. – Paul Fitzgerald Jun 01 '15 at 20:33
  • 1
    Maybe you are facing a cross-domain Ajax request problem. You can try to set some options properly for cross-domain requests. This page has the documentation for that: http://api.jquery.com/jquery.ajax/ – Fabiano Jun 01 '15 at 20:34
  • 1
    @Fabiano And what properties would that be? i see no missing properties in his code that would make a CORS request work. – Kevin B Jun 01 '15 at 20:35
  • 1
    Make sure your server is setup to properly respond to the preflight (OPTIONS) request . – Kevin B Jun 01 '15 at 20:37
  • 1
    There is a note for the contentType parameter: "Note: For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server." Did you try to change the contentType to one of these accepted for cross-domain requests? Maybe it works. – Fabiano Jun 01 '15 at 20:37
  • @War10ck I've changed the position of the Content-Type header in both the curl and ajax request. – Christina Leuci Jun 01 '15 at 20:45
  • @PaulFitzgerald This is a post request since it is sending the data to the url – Christina Leuci Jun 01 '15 at 20:46
  • @Fabiano I've tried all three suggestions for content-type but nothing has worked. – Christina Leuci Jun 01 '15 at 20:47
  • 1
    Well, an error 500 tells us that some error occurred on server side. The page eGalaxy.aspx is throwing an error, maybe an yellow page. What the page eGalaxy.aspx tells to you? Can you post the error throwed by the server-side? – Fabiano Jun 01 '15 at 20:54
  • The error received from the url is: ` soapenv:Server Policy Falsified https://client-url/eGalaxy.aspx ` This happened when the xml was not properly sent to the url. – Christina Leuci Jun 01 '15 at 20:58
  • 1
    @ChristinaLeuci, I've noticed that your web.config is not a valid config file. It has the .txt extension, and this makes the web.config invalid. The ".config" is the real extension.. By default, Windows put the .txt extension on all text files you create. Rename the file removing the .txt extension. The full name of the web.config is actually web.config. Try it and tell me what you get. :) – Fabiano Jun 03 '15 at 18:48
  • 1
    @ChristinaLeuci you can check if the extension is correct by looking to the "type" column on the list. The screenshot you put is marked with "Text document" and the correct form for web.config is "CONFIG File". Check it out. :) – Fabiano Jun 03 '15 at 18:51
  • @Fabiano I needed to change the name of the file for it to open, it gave me that error I posted as a config file – Christina Leuci Jun 03 '15 at 19:11
  • 1
    Have you tried to put Response.AppendHeader("Access-Control-Allow-Origin", "*"); on the code behind of eGalaxy.aspx? (eGalaxy.aspx.cs) This could work. Let's try all the options... hehe – Fabiano Jun 03 '15 at 19:37
  • I'm afraid I don't understand where this needs to be put. Do I put this on the var url line? – Christina Leuci Jun 03 '15 at 19:48
  • 1
    This is easy to do: open your eGalaxy.aspx.cs and you will notice that it has a method called "Page_Load". This line must be the very first instruction of this method. If the method does not exist, then you just need to create: protected void Page_Load(Object s, EventArgs e) { Response.AppendHeader("Access-Control-Allow-Origin", "*"); } This method will run on the server every time someone loads the page. It is like the window.onload method on Javascript. Got it? – Fabiano Jun 03 '15 at 19:57
  • The eGalaxy.aspx is on the client side, I have no access to the code. – Christina Leuci Jun 03 '15 at 19:58
  • 1
    The xhr.AppendHeader is a function that does not exist in XMLHttpRequest object. You have to set this header this way on your JS code, right after the .open() call: xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); Tell me if this solves your problem. – Fabiano Jun 03 '15 at 21:16
  • So I ended up needing to put the setRequestHeader method after both my open() calls and before my send() call. Now I need to figure out why the send call is being considered anonymous. – Christina Leuci Jun 03 '15 at 21:51

1 Answers1

1

There is an error in your XML. You put version:"1.0", and this makes the XML invalid. Change to version="1.0" and try to make your request. It should work. This may be the cause for the "Bad request" error.

You can validate your XML here: enter link description here

EDIT: After some research, the problem may be with the headers sent by your server. Your server (or page, .aspx in this case) seems to skip the header you need, the "Access-Control-Allow-Origin: *".

Look at this link: http://enable-cors.org/server.html This site shows you how to implement it for your server. Since the page you are requesting is called eGalaxy.aspx, then you have 2 ways to implement the headers:

1- Put the line Response.AppendHeader("Access-Control-Allow-Origin", "*"); if the page is a simple ASP.NET application. If it uses Web API 2, you need to implement a different way as it is shown here: http://enable-cors.org/server_aspnet.html

2- Edit the web.config file on the root of your server and add these lines inside the tag:

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

For a ASP.NET application, these are the ways you have. The link I mentioned has solutions for other applications, take a look and choose the right one. :)

Note that the value * tells you that your server will accept any cross-origin request. This may lead to a security issue, so the best you can do is to put your domain address instead of *.

I hope it helps!

Fabiano
  • 5,001
  • 2
  • 28
  • 31
  • Thank you for letting me know about the error! Unfortunately it didn't help – Christina Leuci Jun 01 '15 at 22:31
  • 1
    Have you looked into this thread? http://stackoverflow.com/questions/3595515/xmlhttprequest-error-origin-null-is-not-allowed-by-access-control-allow-origin It looks like a problem like yours. I see no problem with your headers, but maybe the solution of this thread could work for you. – Fabiano Jun 02 '15 at 15:09
  • 1
    You can read this article too about CORS: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/ I think that you won't have future problems with this, because once the origin is allowed by the server then the CORS request will always be accepted. Access-Control-Allow-Origin =! 'null' suggests your request is not sending the Access-Control-Allow-Origin. Your request should send "*" value or your client address. Once you send this and this address is on the server's white list, then the request should work fine. I hope it makes sense to you and helps you. – Fabiano Jun 02 '15 at 15:31
  • I used something similar to what I added to the update in my post: var url = client-url; var data = xml-string; function createCORSRequest(method, url){ var xhr = new XMLHttpRequest(); if("withCredentials" in xhr){ xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined"){ xhr = new XDomainRequest(); xhr.open(method, url); } else{ xhr = null; } return xhr; } var request = createCORSRequest('POST', url) if (request){ request.onload = function(){ console.log(request.responseText); }; request.send(data); } I receive the Origin error and the xhr.send() = anon error – Christina Leuci Jun 02 '15 at 16:27
  • 1
    I've found another useful tutorial about CORS: http://www.html5rocks.com/en/tutorials/cors/ On the black screen you posted here, I couldn't see the "Origin" header being sent from the server. Is your server configured to allow CORS requests? Maybe some configuration on server side is missing, because your code looks OK. – Fabiano Jun 02 '15 at 19:21
  • I linked this tutorial in my edit. How can I ensure that my server is configure to allow CORS requests? I'm only using a local index.html file to run javascript. – Christina Leuci Jun 02 '15 at 20:30
  • 1
    What is the web server that you are using? IIS, Apache... do you know? There is some configuration to be done on it. Let me know what you are using. – Fabiano Jun 02 '15 at 21:52
  • 1
    And sorry for the duplicated link... I didn't see it hehe – Fabiano Jun 02 '15 at 21:53
  • 1
    I believe it is Apache since that is the server on my curl image but I can't be positive until I get home from work in about 30 minutes. By the way thank you for all this help! – Christina Leuci Jun 02 '15 at 21:56
  • 1
    You're welcome! I will post another suggestion editing my answer. – Fabiano Jun 02 '15 at 22:04
  • Confirmed, Apache is the Mac's default server – Christina Leuci Jun 02 '15 at 22:31
  • 1
    Cool, then is far more simple than asp.net. Try to follow the instructions on the link for Apache (http://enable-cors.org/server_apache.html) and let me know if it works. :) – Fabiano Jun 02 '15 at 22:33
  • I am so sorry I gave the wrong information last night in my excitement, I am remote-ing from a MAC into a Windows 2010 computer, the IIS version is 7.5. I just added an edit explaining what options I used and what happened. – Christina Leuci Jun 03 '15 at 16:28