I've got a request from an html page to a Node service.
The service works perfectly in Firefox and Chrome when accessed through url. Works perfectly when I use curl and also with Postman.
When I use XMLhttpsRequest it launches the onerror associated function and end up with readyState 4, status 0.
I don't know why, at a given time Firefox let me know through the developer's console that I was cross accessing (Tho I am accessing localhost, but I won't loose it for it) (By the way: I never received the "crossing" message again I surely touch a sensible key with my console.logs that I should have erased)
So I incorporated this midleware to my server:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
When I run it in Chrome it says:
GET https://localhost:3000/oficina/9999 net::ERR_CONNECTION_CLOSED
I swear that's not true.
My Ajax code is this:
function accede(accion,url,fn) {
var xobj = new XMLHttpRequest();
// console.log("accion: ", accion);
// console.log("url : ", url);
xobj.overrideMimeType("application/json");
xobj.open(accion, url, true);
xobj.onerror = (e) => {
alert("Error del Navegador!!!\nStatus: " +xobj.status +" (" +xobj.statusText+")")
console.log("Falló, Header:")
console.log(xobj.headers)
}
xobj.onprogress = (e) => {
console.log("Progress: ")
}
xobj.onreadystatechange = () => {
console.log("State:",xobj.readyState,"Status:", xobj.status)
if (xobj.readyState == 4 && xobj.status == "200") {
console.log("Fifó!")
}
};
xobj.onload = () => { fn(JSON.parse(xobj.responseText)) };
xobj.send();
}
The whole code is in:
https://github.com/elmasbestia/bnsvr
May somebody help me?
why don't you get the javascript code from postman
I tried 2 methods . from chrome and form console. both work
I get 500's due to exception on the server though
also, why are you using https? i don't see your express server being https
Related
I used Angular HTTP while testing in the browser and it worked fine, but it doesn't on an actual mobile device... Apparently HTTP angular doesn't work on mobile and I had to convert the post request to ionic native HTTP. I'm not sure if it's converted correctly and what the issue is...
Also, the get requests work fine is only the post requests that don't work.
Hope someone can help me with this. Thanks in advance!
My code :
angular HTTP post request
senduserdata(username){
var dataToSend = {
username:this.Username,
password:this.Password,
usertype:this.getSelectedSubject,
}
var url = 'https://mylink.herokuapp.com/login';
this.http.post(url,{data:JSON.stringify(dataToSend)},{responseType: 'text'}).subscribe(
(data)=>{
alert(data);
if(data === "Logged In Successfully!")
{
this.LoginCustomer();
this.cartservice.setUsernameCustomer(this.Username);
}
else if(data === "Welcome!")
{
this.LoginStaff();
this.cartservice.setUsernameStaff(this.Username);
}
}
)
}
ionic advanced HTTP post request
senduserdata(){
var dataToSend = {
username:this.Username,
password:this.Password,
usertype:this.getSelectedSubject,
}
var url = 'https://mylink.herokuapp.com/login';
this.http.post(url,{data:JSON.stringify(dataToSend)},{responseType: 'text'}).then(
(data)=>{
this.message= JSON.parse(data.data);
alert(this.message)
if(this.message === "Logged In Successfully!")
{
this.LoginCustomer();
this.cartservice.setUsernameCustomer(this.Username);
}
else if(this.message === "Welcome!")
{
this.LoginStaff();
this.cartservice.setUsernameStaff(this.Username);
}
}
)
}
Update
Turns out it works on the browsers cause I was using CORS changer extensions,
I just had to add in my node.js file
app.all('*', function(req, res, next) {
var origin = req.get('origin');
res.header('Access-Control-Allow-Origin', origin);
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
var app = express();
var cors = require('cors');
app.use(cors())
Searched all over google and here and tried a few things. The page I've setup can only have Javascript code. I've tried the below for a request to pull some details. It works on Chrome and other browsers just not on Safari. I get a "Failed to load resource: the server responded with a status of 404 ()" on Safari v13.1.
Assuming this needs different headers sending for Safari or CORS is causing some issue. Not sure on this. Have tried the fetch method and that's not worked and given the same problem. I'm sure a lot of people have had this issue and found a fix for it in JavaScript. Any help on this would be greatly appreciated.
XML Request JS
var xhr = new XMLHttpRequest();
console.log(xhr);
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return; {
console.log(JSON.parse(xhr.responseText));
}
};
xhr.open("GET", "/api/storefront/orders/" + buildOrderID() + "");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.send();
Fetch Request JS
fetch("/api/storefront/orders/" + buildOrderID() + "").then(function (response) {
// The API call was successful!
return response.json();
}).then(function (data) {
// This is the JSON from our response
console.log(data);
}).catch(function (err) {
// There was an error
console.warn('Something went wrong.', err);
});
I have server and a client the server uses node js the client send requests to the sever and the server should act accordingly.
However I came across a little bit of a confusing behavior and i want to know why its behaving like that!
The thing is when i send a json array or Object the received data by the server is always empty for some reason.
Here is the code of the request that raises the problem:
function Save()
{ // saves the whole global data by sending it the server in a save request
if( global_data.length > 0)
{
var url = "http://localhost:3000/save";
var request = new XMLHttpRequest();
request.open("POST", url, true);
request.setRequestHeader("Content-Type", "application/json");
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
console.log(this.responseText);
}
};
let object={ id: "101.jpg", RelativePath: "images/101.jpg", size: 61103 }; // this just an exemple of data
let data_json = JSON.stringify(object);
request.send(data_json);
}
else
{
console.log("Nothing to save");
}
}
And Here is the server code related to this request:
const server=http.createServer(onRequest)
server.listen(3000, function(){
console.log('server listening at http://localhost:3000');
})
function onRequest (request, response) {
/*function that handles the requests received by the server and
sends back the appropriate response*/
/*allowing Access-Control-Allow-Origin since the server is run on local host */
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Request-Method', '*');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', '*');
console.log("a request received :" ,request.url);
let parsed_url = url.parse(request.url);
if(parsed_url.pathname == '/save')
{
console.log("Proceeding to save state : ...");
let received_data = '';
request.on('data', function(chunck) {
received_data += chunck;
console.log("another line of data received");
});
request.on('end', function() {
console.log(received_data); // why is this empty (my main problem)?
let jsondata = JSON.parse(received_data); // here raises the error since the received data is empty
console.log(jsondata);
response.writeHeader(200,{"content-Type":'text/plain'});
response.write("SAVED!");
response.end()
});
}
}
Just if anyone got the same problem: for me I couldn't solve it directly so I was forced to use query-string in order to parse the data instead of json.parse it seems the data received emptiness was related to the failure of the JSON parser somehow. so I installed it with npm install querystring and used const qs = require('querystring'); in order to invoque the parser by calling qs.parse(received_data.toString());.
Hope this helps anyone who got stuck in the same situation.
I'm having a problem related to cors, I can't get rid of famous
XMLHttpRequest cannot load external domain.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'mydomain.com' is therefore not allowed access
What I tried:
http://www.html5rocks.com/en/tutorials/cors/ - End-to-End Example , still doesnt work , getting the same error.
https://www.sencha.com/forum/showthread.php?299915-How-to-make-an-ajax-request-cross-origin-CORS
other various examples
// Create the XHR object.
function createCORSRequest(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.
function getTitle(text) {
return text.match('<title>(.*)?</title>')[1];
}
// Make the actual CORS request.
function makeCorsRequest() {
// All HTML5 Rocks properties support CORS.
var url = 'http://updates.html5rocks.com';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
var title = getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
Example above only works in launching static html when I upload it to main domain I'm getting error which I mentioned above.
I just found how to do it with http://cors.io/ .
http://cors.io/?u=http:(your url without brackets)
WORKS LIKE A CHARM.
THANK YOU TO EVERYONE WHO CONTRIBUTED.
Make sure on your server Access-control-allow-origin is set to *
Assuming lets say its nodejs
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
I am running a nodejs server to run my website, and I want the backend server to make a call to an api on an external server. I tried the following, basic and straightforward method:
router.post('/calculate', function (req, res) {
var data = /*some json object*/
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "some.server/pricing");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify(data));
xmlhttp.onreadystatechange = function() {
if(xmlhttp.status == 200)
{
var str = xmlhttp.responseText.toString().trim()
dd = JSON.parse(str);
res.send(dd);
//res.end();
}
};
});
When I run this I get:
_http_outgoing.js:346
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
The issue seems to be in res.send(dd);
EDIT:
Upon further investigation, it seems like xmlhttp.onreadystatechange happens twice with status 200, and res.send is called twice. I created a temporary hack to fix this using a boolean flag, what is the rpoper nodejs way to fix this?
What is the most straightforward way of making such a call in nodejs? I want this done on the server side. I am not using any libraries like express. Thanks
Easy do it with request package
var request = require('request');
request({
url: 'some.server/pricing',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
form: data
}, function (err, res, body) {
if (err) res.send(err)
else res.send(body)
});
After a lot more investigation, I found out that res.send was being called twice. The reason this was happening was because the xmlhttp object changes its state several times:
http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp
I fixed the code to:
if (xhttp.readyState == 4 && xhttp.status == 200)
Now everything works properly.