simple ajax request to localhost nodejs server - ajax

I wrote very simple server :
/* Creating server */
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
});
/*Start listening*/
server.listen(8000);
I run it using nodejs.
Now i want to write simple client that use ajax call to send request to server and print response (Hello World)
Here javascript of clinet:
$.ajax({
type: "GET",
url: "http://127.0.0.1:8000/" ,
success: function (data) {
console.log(data.toString);
}
});
When I open client html file i get following error in console:
XMLHttpRequest cannot load http://127.0.0.1:8000/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I tried adding to ajax call following:
$.ajax({
type: "GET",
url: "http://127.0.0.1:8000/" ,
dataType: 'jsonp',
crossDomain: true,
success: function (data) {
console.log(data.toString);
}
});
But then i get
Resource interpreted as Script but transferred with MIME type text/plain: "http://127.0.0.1:8000/?callback=jQuery211046317202714271843_1410340033163&_=1410340033164".
Anyone can explain what i did wrong and perhaps how to fix it?
Many thanks!

To overcome the CORS, in your node.js file write the below, based on what you need:
// 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);

The first error is caused by CORS (Cross Origin Resource Sharing) policy. It's rule by all browsers that you cannot make a request to a remote server in AJAX other than to the current server the script/page was loaded from unless that remote server allows it via Access-Control-Allow-Origin header.
I suggest serving the page from the same Node.js server. Then it will work. Example, when the request comes to root / page, then serve the index.html file, otherwise, server whatever other content you want.
var http = require('http'),
fs = require('fs');
/* Creating server */
var server = http.createServer(function (request, response) {
if (request.url == '/' || request.url == '/index.html') {
var fileStream = fs.createReadStream('./index.html');
fileStream.pipe(response);
} else {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
}
});
/*Start listening*/
server.listen(8000);

Related

How to perform a Ajax Request via browser to AWS API Gateway with CORs Policy?

I performed a GET request via Postman successfully, but it is failing in the browser due to CORs
I've tried both XHR and Jquery Ajax (see codepen here), and I've also set Access-Control-Allow-Origin
XHR
var data = "{\"value\":'174.9',\"time_stamp\":\"2019-10-01T18:56:45-04:00\",\"date\":\"2019-10-01\",\"name\":'weight',\"category\":'weight'}";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("GET", "https://f17c15m5a79.execute-api.us-east-2.amazonaws.com/production/quantified-self-metrics");
xhr.send(data);
Jquery Ajax
var settings = {
async: true,
crossDomain: true,
url:
"https://f17c15m5a79.execute-api.us-east-2.amazonaws.com/production/quantified-self-metrics",
method: "GET",
headers: {
"Access-Control-Allow-Origin": "*"
},
data:
'{"value":\'175.9\',"time_stamp":"2019-10-02T18:56:45-04:00","date":"2019-10-02","name":\'weight\',"category":\'weight\'}'
};
$.ajax(settings).done(function (response) {
console.log(response);
});
The response I receive from the browser is the following:
Access to XMLHttpRequest at
'https://f17c15m5a79.execute-api.us-east-2.amazonaws.com/production/quantified-self-metrics?{%22value%22:%27175.9%27,%22time_stamp%22:%222019-10-02T18:56:45-04:00%22,%22date%22:%222019-10-02%22,%22name%22:%27weight%27,%22category%22:%27weight%27}'
from origin 'https://codepen.io' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I've also implemented the solution found in this question
You need to prepend https://cors-anywhere.herokuapp.com/ to your request url.
So it will look like https://cors-anywhere.herokuapp.com/https://f17c15m5a7.execute-api.us-east-2.amazonaws.com/production/quantified-self-metrics

AJAX GET requests with Varnish Cache

I have got an AJAX request running on a server with varnish. The request is as follows:
(function() {
$("#name").autocomplete({
minLength:3, //minimum length of characters for type ahead to begin
source: function (request, response) {
$.ajax({
type: 'GET',
url: php_vars.var_1, //your server side script
dataType: 'json',
data: {
postcode: request.term
},
success: function (data) {
alert("Success");
}
});
}
});
})();
For the url, I use wp_localize_scripts and array with the absolute URL of the php script. I have consoled this url before this script and it is ok.
I have this setup on a server not running with varnish and it works fine. However on my server with varnish, I have noticed that the request URL is not correct (should be "auspost.php" and instead it is the page url with the query params). On my none varnish server the GET request url is correct.
It looks like varnish is caching my GET requests. Any advice would be very much appreciated! I can pastebin my vcl config if need be?
For ajax requests you should have the following header available
X-Reqeusted-With: XMLHttpRequest
In your varnish vcl_recv you can check if this header is present and force a pass.
if (req.http.X-Requested-With == "XMLHttpRequest"){
return (pass);
}

How to enable CORS?

I'm making a request from client side to a web-API on different domain to extract data in JSON format. How do I enable Cross Origin Resource Sharing(CORS)?
Client runs on https while my web-API runs on http.
This is the AJAX call that I'm making :
$(document).ready(function () {
$.ajax({
type: "GET",
url: "http://map.techriff.in/api/values",
success: function (json) {
console.log(json);
},
error: function (err) {
console.log(err);
}
});
});
This site helped me when I had an issue with Chrome showing the following error: "No 'Access-Control-Allow-Origin' header is present on the requested resource"
Go down to the section titled "Enable CORS".
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
Note, I used the following attribute syntax as opposed to what was listed in the site above:
[EnableCors("http://localhost:1616", "*", "*")]
You need to add the Access-Control-Allow-Origin: http://domain.com to your response header, where domain.com is replaced with the domain you want to allow (don't use * wildcards).
How you do this depends one your server stack. In ASP.NET:
Response.AppendHeader("Access-Control-Allow-Origin", "http://domain.com");
You then need to set $.support.cors = true in your jQuery to enable it on the client.
Add $.support.cors = true; somewhere before to make your $.ajax call.
Source: Is it safe to use $.support.cors = true; in jQuery?
Assuming you correctly set the Access-Control-Allow-Origin header on the server as well.
CORS jQuery AJAX request
First of all, this is a big issue. Everyone will say you have to enable CORS in the server. What if we are requesting an API?. What I did is.
Step 1: Make an ajax call to my own server.
Step 2: Make https request from my server to the API.
Step 3: Send the result to the ajax.
My AJAX call.
$.ajax({
type: "POST",
url: "makepay",
data:{
key:value
},
success: function(response) {
//place to handle the response
},
error: function() {
//place to handle the error
}
});
My server page
const https = require('https');
app.post('/makepay',function(req, res){
var options = {
host: "Site address",
path: "Path",
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
var req = https.request(options, (resp) => {
resp.on('data', (xmlresponse) => {
res.send(xmlresponse);
}}
req.write(parameters_to_the_API);
req.end();
});
I hope you will get at least the idea.

FireFox doesn't send cross-domain ajax?

Here is a problem: when user make authorisation on one server (e.g. a.com) he should be authorised (over jQuery-ajax) on another server (e.g. b.com) - the user-DB is shared for both this sites. Js-code written is
var form = jQuery('#auth_form');
var data = form.serialize();
var url = 'http://www.b.com/auth';
jQuery.ajax({
url: url,
crossDomain: true,
type: 'POST',
dataType: 'html',
data: data,
xhrFields: {
withCredentials: true
},
success: function (html) {
},
error: function (jqXHR, textStatus) {
}
});
When server send response, he set some of header
header("Access-Control-Allow-Origin: http://www.a.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: POST,GET,OPTION");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: x-requested-with, Content-Type, origin, authorization, accept, client-security-token");
It works fine in Chrome and Opera, but ForeFox seems even dousn't send request to server and writes something like this in console log:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.b.com. This can be fixed by moving the resource to the same domain or enabling CORS.
FireFox is latest version (37.0.1) and it's written that version 3.5+ supports CORS and i don't understand what is going wrong? I've tried look network through Fiddler - and i don't see request to b.com from FireFox (from Chrome i see one - everything is Ok). I've tried manage FireFox options (capability.policy.default.XMLHttpRequest.open = allAccess), but it doesn't work. Where is any solution? Any help will be appreciated.

Can't retrieve my x-api-key from my request header with CORS enabled. Why?

I'm working with CodeIgniter2 Rest API and AJAX to make requests from a smartphone with PhoneGap to a AWS server with apache.
Everything was working fine when working on my localhost/browser.
But when trying to set up a distant server things got bad.
I have configured my server properly with CORS so that it allows external requests as explained here :
http://dev.nuclearrooster.com/2011/01/03/cors-with-apache-mod_headers-and-htaccess/
To secure the API, I have been setting up an API KEY that I have to pass in the header of my request like so:
$.ajax({
type:"GET",
url: server_url + 'user/available',
headers: { 'X-API-KEY': key },
dataType: 'json'
});
But then, after seeing my ajax called being refused because of an invalid API Key, I have been trying to make sure the server received the key. and it doesnt. when I try to echo my key, its empty.
I can see in my debug console the following:
Request header field X-API-KEY is not allowed by Access-Control-Allow-Headers.
So I have been modifying my .htaccess following this post:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type, x-api-key"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
so now, the message is gone but the problem still remains the same ... why ?
How can I transmit this X-API-KEY through my AJAX call Header so I can authentificate my users ?
Many Thanks
I faced this problem and with weeks of tweaking I was able to get it to work with a hack of a job... I can't remember the exact part that did fix it but will provide with what I am currently using.
Server Side
function __construct(){
parent::__construct();
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Headers: X-API-KEY");
}
function available_options(){
$this->response(array('response' => array()), 200);
}
Client Side
function sendData(dataToSend, successCallback) {
window.default_headers['X-API-KEY'] = '_KEY_';
return $.ajax({
type: "POST",
url: server_url + 'user/available',
data: { data : JSON.stringify(dataToSend) }, // serializes the form's elements.
dataType: 'json',
headers: window.default_headers,
xhrFields: {
withCredentials: true
}
});
}
Since you're using a GET request, possibly using JSONP would be of more use, this avoids cross domain requests.
JSONP Request
$.ajax({
type : "GET",
dataType : "jsonp",
url: server_url + "user/available?callback=?", // ?callback=?
success: function(data){
// do stuff with data
}
});

Resources