Everything is good - when i send request like this :
function toServer2(url, type, data, success) {
var XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest;
var xhr = new XHR();
xhr.open(type, url, true);
xhr.send();}
415 response - when i send request like this :
function toServer2(url, type, data, success) {
var XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest;
var xhr = new XHR();
xhr.open(type, url, true);
xhr.send(data);} // data = "{'name': 'Ben', count: 12}"
No 'Access-Control-Allow-Origin' - when i send request like this:
function toServer2(url, type, data, success) {
var XHR = ("onload" in new XMLHttpRequest()) ? XMLHttpRequest : XDomainRequest;
var xhr = new XHR();
xhr.open(type, url, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(data);} // data = "{'name': 'Ben', count: 12}"
The server that receives the AJAX call must send the CORS header within the response, as it's on a different port. Check this: http://www.html5rocks.com/en/tutorials/cors/
Related
I'm trying to create a tournament using api.challonge.com
When attempting to do so in node.js, it works fine with this code:
request.post("https://api.challonge.com/v1/tournaments.json", {
"json":{
"api_key":API_KEY,
"name":"MyTourney",
}
}, function (error, response, body) {
console.log(body);
});
However, when attempting to do it with an XMLHttpRequest in javascript, I am getting error 422. This is the code:
var fd = new FormData();
fd.append("api_key", API_KEY);
fd.append("name", "MyTourney");
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://api.challonge.com/v1/tournaments.json", true);
xhr.onreadystatechange = function() {
console.log(xhr.responseText);
};
xhr.send(fd);
I don't understand why the request is successful in the node request, but not in the XMLHttpRequest
Here is a screenshot of the browser console:
Nothing I do works, and I keep getting ridiculous CORS errors and other things. I just want to do a normal oath to log a user in, through the browser. I want to use snoowrap, but I can't even get far enough to use it, because i need a refresh token.
I already authorize the app and get the 'code' back from the API, which im then supposed to use by making a post request to https://www.reddit.com/api/v1/access_token.
But I just get CORS errors every time.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.reddit.com/api/v1/access_token. (Reason: missing token ‘access-control-allow-headers’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.reddit.com/api/v1/access_token. (Reason: CORS request did not succeed).
code:
const redirect_uri = 'https://EXAMPLE.com/reddit/';
const client_id = 'xxxxxxxxxxxxx';
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); /*global URLSearchParams*/
const code = urlParams.get('code');
var snoowrap = window.snoowrap;
if (code) {
console.log('code gotten', code);
const data = {
grant_type: 'authorization_code',
code: code,
redirect_uri: redirect_uri
};
ajax('https://www.reddit.com/api/v1/access_token', data, 'Basic client_id:', result => {
console.log(result);
const r = new snoowrap({
userAgent: 'skeddit',
clientId: client_id,
clientSecret: 'fFP-6BKjFtvYpIkgFGww-c6tPkM',
refreshToken: '',
});
r.getHot().map(post => post.title).then(console.log);
});
}
//GET: ajax(String url, Function success)
//POST: ajax(String url, Object postData, Function success)
function ajax(url, arg2, arg3, arg4) {
if (typeof arg2 == 'function')
var success = arg2;
else {
var postData = arg2;
var headers = arg3;
var success = arg4;
}
console.log('AJAX - STARTING REQUEST', url)
//start new request
var xhttp = new XMLHttpRequest({mozSystem: true});
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
success(JSON.parse(this.response));
xhttp = null;
console.log('AJAX - COMPLETE', this.response);
}
};
if (postData) {
//post request
console.log('post data: ', postData);
var formData = new FormData();
for ( var key in postData ) {
formData.append(key, postData[key]);
}
xhttp.open("POST", url, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.setRequestHeader("Authorization", headers);
xhttp.send(formData);
}
else {
//get request
xhttp.open("GET", url, true);
xhttp.send();
}
return xhttp;
}
I don't even understand why something would prevent me from doing a POST request to a public api
After hours of searching I found a solution:
If you're creating a browser-only JS app (no server), you should select your app type as "installed app" (instead of "web app") in the reddit console.
Then you have to send an Authorization header whose value is your Client Id, as stated here reddit/wiki/OAuth2
const fd = new FormData();
fd.append("code", code);
fd.append("grant_type", "authorization_code");
fd.append("redirect_uri", "your_redirect_uri");
const r = await fetch("https://www.reddit.com/api/v1/access_token", {
headers: {
Authorization:
"Basic " + btoa(unescape(encodeURIComponent(CLIENT_ID + ":" + ""))),
},
method: "POST",
body: fd,
});
I am trying to upload an image using fetch instead of xhr. My request works successfully when I use xhr. My xhr request object is the following
var data = new FormData();
var photoObject = {
uri: uriFromCameraRoll,
type: 'image/jpeg',
name: 'photo.jpg'
};
data.append("photos", photoObject);
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "http://localhost:3000/api/v1/");
xhr.send(data);
Now I am trying to use fetch like following
fetch('http://localhost:3000/api/v1/', {
mode: 'no-cors',
method: 'POST' ,
body: data
}).then(function(response) {
console.log(response.status)
console.log(response)
})
But in my sever I am not receiving the file. Can anyone help me resolve this issue?
THE SITUATION:
I am making an app in AngularJs.
I need to make a CORS request to fetch data from an api on a different address.
On the api i output a very simple json, for test purpose:
[{"id":0,"name":"First"},{"id":1,"name":"Second"},{"id":2,"name":"Third"}]
I need to fetch these data and display on my app.
$HTTP CALL:
making the $http call i get the following error, because the api is on a different domain:
No 'Access-Control-Allow-Origin' header is present on the requested resource
CORS REQUEST - THE CODE:
// Create the XHR object.
$scope.createCORSRequest = function(method, url)
{
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr)
{
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
}
else if (typeof XDomainRequest != "undefined")
{
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
}
else
{
// CORS not supported.
xhr = null;
}
return xhr;
}
// Helper method to parse the title tag from the response.
$scope.getTitle = function(text)
{
return text.match('<title>(.*)?</title>')[1];
}
// Make the actual CORS request.
$scope.makeCorsRequest = function()
{
var url = 'http://DOMAIN.COM/main/json_export_test';
var xhr = $scope.createCORSRequest('GET', url);
console.log('----- xhr -----');
console.log(xhr);
if (!xhr)
{
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function()
{
var text = xhr.responseText;
var title = $scope.getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function()
{
alert('Woops, there was an error making the request.');
};
xhr.send();
}
When i run the function makeCorsRequest i get the alert called by xhr.onerror
But i have no clues why it isn't working.
THE API:
This is the very simple php function in the api, for test purpose:
public function json_export_test()
{
$data = array(
array(
"id" => 0,
"name" => "First"
),
array(
"id" => 1,
"name" => "Second"
),
array(
"id" => 2,
"name" => "Third"
)
);
echo json_encode($data);
}
THE QUESTION:
How can i make a simple CORS request?
EDIT - THE SOLUTION:
This is how it looks the api after having edited it, thanks to the reply:
public function json_export_test()
{
header('Access-Control-Allow-Origin: *');
$data = array(
array(
"id" => 0,
"name" => "First"
),
array(
"id" => 1,
"name" => "Second"
),
array(
"id" => 2,
"name" => "Third"
)
);
echo json_encode($data);
}
In general: You just make a normal request using XMLHttpRequest. The browser will handle the rest. (The exception is in old browsers which either don't support CORS or which require you to use XDomainRequest instead of XMLHttpRequest — but you seem to be accounting for that already).
The error message you are getting indicates that you are not getting a CORS response, so the browser doesn't have permission to give the other site's data to your JavaScript.
You need to include Access-Control-Allow-Origin: * (or something more specific) in the HTTP response to the cross-origin request.
I have an existing java client on top of which IOS, andriod developers prepared a simple http request based applications. And am trying to achieve same in HTML5 app.
And the difficulty right now am facing is sending an custom header within the AJAX request like authorization with encrypted login details.
I tried to achieve same on various REST clients and able to send "AUTHORIZATION : BASIC XXXXXX=" in request header. And getting proper json response"
But if i try same using ajax call am not able to send similar request header. Request sending as OPTIONS instead of GET and the authorization tag is not going properly as a header instead it's going as "Access-Control-Request-Headers:authorization".
and here is the snippets i have tried.
<script>
//$.ajaxSetup({ headers: { 'Authorization': 'Basic XXXXXXX='} })
// get form data for POSTING
var vFD = new FormData(document.getElementById('upload_form'));
var oXHR = new XMLHttpRequest();
oXHR.open('POST', "https://123.123.123.123:229/");
//oXHR.send(vFD);
var body = 'Basic XXXXXXX=';
var mUrl = "https://123.123.123.123:229/?json";
var client = new XMLHttpRequest();
client.open('GET', mUrl, true);
client.withCredentials = true;
client.crossDomain = true,
client.setRequestHeader('Authorization', 'Basic XXXXXXX=');
client.send(body);
simpleHttpRequest();
function simpleHttpRequest() {
alert("calling ");
var headers = {
"Authorization": "Basic XXXXXXX="
};
$.ajaxSetup({ "headers": headers });
$.ajaxSetup({ 'cache': false });
$.ajax({
type: "GET",
withCredentials: true,
// data: {
// address: 'http://www.google.com'
// },
crossDomain: true,
Headers: { "Authorization": "Basic XXXXXXX=" },
dataType: "jsonp",
url: mUrl,
cache: false
});
}
xhrToSend();
function xhrToSend() {
// Attempt to creat the XHR2 object
var xhr;
try {
xhr = new XMLHttpRequest();
} catch (e) {
try {
xhr = new XDomainRequest();
} catch (e) {
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {
statusField('\nYour browser is not' +
' compatible with XHR2');
}
}
}
}
xhr.withCredentials = true;
xhr.open('GET', mUrl, true);
xhr.setRequestHeader("Authorization", "numberOfBLObsSent");
xhr.send();
};
</script>
And all the different ways getting failed. Please help me.
Thanks in advance.
The issue is related to the cross-domain nature of the request. When you make a cross-domain request which contains custom headers, the request is first "preflighted" to the server via the OPTIONS method, and the server must respond with a header Access-Control-Allow-Headers: your-custom-header. Once this is received, the ajax client will then (automatically) issue the actual request.
More on preflighted requests