I'm working on a consumer for a self-made API and having serious difficulties with setting the Authorization header. I am using JQuery for the Ajax requests, but the 'beforeSend' does not work at all (using fiddler to examine the requests)
This is my beforeSend code:
$.ajax({
type: "GET",
url: url+"/Projects",
contentType: "application/json; charset=utf-8",
beforeSend: function (req) {
req.setRequestHeader("Authorization", AuthBuilder(username, password));
},
success: function (result) {
alert("success");
},
error: function (xhr, ajaxOptions, thrownError) {
alert("fail");
}
});
Well if that fails what do you do? Go back to the old way for sending ajax requests... well this doesn't work either...
This is my regular code:
function GET(address, callback, error) {
Request = getXMLHttpObject();
Request.open("GET", url + address, true);
var base64 = Base64.encode(username + ":" + password);
alert(base64);
Request.setRequestHeader("Authorization", "Basic " + base64);
Request.send();
Request.onreadystatechange = function () {
//alert(Request.readyState+" code "+Request.status);
if (Request.readyState == 4 && Request.status == 200) {
callback(jQuery.parseJSON(Request.responseText));
} else if (Request.readyState == 4 && Request.status >= 400) {
error(Request.status, Request.statusText);
}
}
}
Don't mind the fact that I'm not asking for json specifically because the service returns json by default.
In additional info:
the origin does not matter, the service allows all origins (has been tested and confirmed)
the Authorization works when set by headers (tested in other clients)
the Authorization headers just aren't sent
AuthBuilder(username, password)) gives the correct format of the Basic Auth header content
the getXMLHttpObject() is just some copy paste code and worked before
any thoughts ?
Well I found out what the problem was. The self-made service sent this back to the client as a global header : "Access-Control-Allow-Headers" with only "Content-Type" in it.
This way our clients not using an User Agent (browser) ignored these headers and just sent the header anyway. But the browser tried to optimize the request and said "It won't accept the Authorization header so I'll just cut it before sending." this way is the package is smaller and the service won't allow it anyway (although it did...)
So just adding "Authorization" to the Access Control Allow Headers part of the service made my Javascript/JQuery/Ajax requests send the request header as normal!
Related
Hello I am using this method to read this api it giving CORS error. I have added CORS plugin with chrome then also it is not coming. Please let me know how to solve these to error.
text:
function NoCors() {
debugger;
var uName = "*****";
var passwrd = "*****";
document.write("Enter1");
var url = 'http://219.90.67.163:8207/api/Info/getgismeterdata'
$.ajax({
type: 'GET',
url: url,
crossDomain: true,
//Access-Control-Allow-Credentials: true,
contentType: 'json',
datatype: "application/json",
headers: {
"Authorization": "Basic QXBpVXNlcjpBcGlQYXNz",
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', "Basic " + btoa(uName + ":" + passwrd));
},
success: function (data) {
debugger;
console.log("data")
//Success block
},
error: function (xhr, ajaxOptions, throwError) {
//Error block
},
});
}
error in console:
1. Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
2. Access to XMLHttpRequest at 'http://219.90.67.163:8207/api/Info/getgismeterdata' from origin 'http://localhost:50362' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Before sending the GET request to server, browser automatically send and preflight OPTIONS request, and your server doesn't allow this method. You need to enable OPTIONS method support in your server side (219.90.67.163)
Are you use Bearer Token Authentication?
requst headers try this
headers: {
"Authorization": "Bearer QXBpVXNlcjpBcGlQYXNz",
},
You must setting CORS in Web API
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
The CORS plugin you are using only works for Simple Requests.
Since you are setting an Authorization header you are making a Preflighted Request which your plugin cannot handle.
You need a different approach to handling the Same Origin Policy. Ideally, that would be proper support for CORS on the server you are making the HTTP request to but some other options are listed at the end of this answer.
I am trying to make a cross domain post call in IE9 below is my code:
$.support.cors = true;
var data = {"userid":uid,"email":email,"password":password};
if (isIE () && isIE () <= 9) {
$.ajax({
type: 'post',
crossDomain: true,
url: postUrl,
cache:false,
contentType: 'application/json; charset=utf-8',
dataType: 'jsonp',
data:data,
jsoncallback:'localJsonpCallback',
jsonp:false,
success: function (data) {
console.log(data);
},
error: function (status){
console.log(status);
$("#error").html("Incorrect E-mail Entered. Please Re-Enter Your E-mail ");
}
});
}
function localJsonpCallback(json) {
if (!json.Error) {
alert("success");
}
else {
alert(json.Message);
}
}
However, When I look at the call in fiddler I am getting a 405 error and the request header is showing a GET:
GET postUrl?format=json&userid=123456&email=test%40test.com&password=Password1&_=1434232587917 HTTP/1.1
Why is it if I am making a post that in the request header it is showing a Get? Am I doing anything syntactically wrong with my call?
Your request looks okay and from the server response you're describing, it's a "problem" with server, HTTP status code 405 means bad method, i.e. server doesn't allow POST requests. But it's still strange that it would translate those to GET, but I still think it's because of server implementation, not an error on your side. You could try with a tool like curl and see what response headers you get, but it won't help much if it's an server bug/error.
If you do not have control over the server, the only things remaining is to contact the owner and ask them to allow post request or send a GET request, although it's really bad to send non-encoded login data.
I want to send XML data from php(domain A) to a remote javascript file(domain B).
I can't have them on the same domain, and I can't have any other files on on domain B.
I've read about sending a JSONP object from php instead of XML, but as I understood from a tutorial, I would need a php proxy on the same domain as where the javascript file is located. tutorial link
(xhr.open("GET", "xmlproxy.php?url=" + escape(url), true); <= this line kinda tells me, that the xmlproxy.php has to be on the same domain as the actuala javascript)
Any suggestions, on how could I do this?
LATER EDIT AFTER ThW's answer
Now I have the following sample code :
The testlog.php file
<?php header('Access-Control-Allow-Origin: *');
print "<Logs><Log><id>Test Log</id></Log></Logs>";
?>
The javascript function that is called on page load:
function getTestLog() {
alert("Gets here!");
$.ajax({
url: "anotherdomain/testlog.php",
data: requestVars,
dataType: 'xml',
success: function(xml){
alert(xml);
},
error: function (xhr, err) {
alert("Error: " + xhr.readyState + "\nstatus: " + xhr.status + "\nerror:" + err);
alert("responseText: " + xhr.responseText);
}
});
}
The problem is, that it's not getting into the ajax thing
If you control the PHP that outputs the XML you can use CORS.
By default Javascript can only open resources from the domain it was loaded. Other resources have to allow that they can be loaded by a Javascript on a different domain.
To do that add a header to the PHP-Script:
header('Access-Control-Allow-Origin: http://javascript-domain.tld');
Or to allow the loading of the XML from anywhere:
header('Access-Control-Allow-Origin: *');
You're using jQuery and here might be a problem if you're not sending the correct content type from PHP.
header('Content-Type: application/xml');
To validate that it is the Cross Domain that it is blocking the reading open you Javascript console in the browser. It should output an error message. In Firefox it is something like:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://domain.tld/path/to/resource. This can be fixed by
moving the resource to the same domain or enabling CORS
If you get the request, it should show up in the Network-Tab of your developer tools and you can validate the HTTP response headers.
Here is simple JS snippet using XHR, it forces the content type.:
var xhr = new XMLHttpRequest;
xhr.overrideMimeType("application/xml");
xhr.addEventListener(
'load',
function (xhr) {
return function () {
if (xhr.status >= 200 && xhr.status < 400) {
console.log(xhr.responseXML);
}
}
}(xhr)
);
xhr.open('GET', 'http://php-domain.tld/script.php');
xhr.setRequestHeader("Accept", "application/xml");
xhr.send();
I am working on a web crawler that can integrate with our partner portals and submit post requests to make bid changes.
The trouble is that the crawler runs in an environment which cannot execute jQuery, only native Javascript.
I have determined that the following AJAX code successfully sends the post request:
$.ajax({
type: "POST",
url: "http://acp.example.com/campaigns/122828",
data: "data-string"
});
Is there a way to translate the above statement into native javascript so that the crawler can execute it?
UPDATE
When executing hex494D49's native Javascript below, I am receiving a "NetworkError: 404 Not Found - http://acp.fyber.com/campaigns/122828" message.
However, when I execute the original AJAX code in firebug, it successfully sends the POST request.
Any idea why the same url would return a 404 error using native Javascript as opposed to AJAX?
Thanks
Sending AJAX request using POST method
var xhr = new XMLHttpRequest();
var url = "url";
var data = "email=hey#mail.com&password=101010";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// do something with response
console.log(xhr.responseText);
}
};
xhr.send(data);
Sending AJAX request using GET method
xhr = new XMLHttpRequest();
var url = "url?email=hey#mail.com&password=101010";
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// do something with response
console.log(xhr.responseText);
}
}
xhr.send();
To avoid unexpected requests to the server, it's a good practice to use encodeURIComponent() method on any user-entered parameters that will be passed as part of a URI.
I need to call OpenMRS REST API from Java script to get data from OpenMRS. Below is my java script code:
function myfunction(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:8081/openmrs-standalone/ws/rest/v1/person?q=John", false);
xhr.setRequestHeader("Authorization: Basic YWRtaW46QWRtaW4xMjM");
xhr.send("");
alert(xhr.status);
}
Where YWRtaW46QWRtaW4xMjM is my base64 coded username:password as explained here. If I do not put the authorization line in the code and check the web app using Firebug, it returns 401 unauthorized status that is expected. But if I put the authorization, nothing is returned and in firebug I do not see any response as well. If I check the URL directly on browser, the page asks for username and password and after giving correct credential, it returns the data normaly. So I am getting some problem of providing the http authentication right from the java script of the app. I have also considered the methods explained here but no luck. Can anyone please help me to authorize the http request right from the javascript?
Here is another similar but different example of how to set the header for authorization purposes, but instead using JQuery and AJAX.
var token = "xyz"
var url = "http://localhost:8081/openmrs-standalone/ws/rest/v1/person?q=John"
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Bearer " + token)
},
})
.done(function (data) {
$.each(data, function (key, value) {
// Do Something
})
})
.fail(function (jqXHR, textStatus) {
alert("Error: " + textStatus);
})
Below is also an example of how you might get an access token using xhr instead of AJAX.
var data = "grant_type=password&username=myusername#website.com&password=MyPassword";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://somewebsite.net/token");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("client_id", "4444-4444-44de-4444");
xhr.send(data);
Beware of cross-site domain requests(if you're requesting a token that's not on localhost or within the domain that you are currently working in), as you'll need CORS for that. If you do run into a cross-domain issue, see this tutorial for help, and be sure you have enabled CORS requests from the API as well.