I am facing a issue of cross origins. I have googled and found some solutions but they are not working in this case. I wonder why.
I am hosting my application in apache tomcat server. And On the application side I am using XMLHttpRequest for request but I am getting "XMLHttpRequest cannot load http://localhost:8888/systeminfo. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access."
Here is the Application js file
function testget()
{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
alert(xhr.responseText);
}
}
alert('Getting data');
xhr.open('GET', 'http://localhost:8888/systeminfo', true);
xhr.setRequestHeader('Access-Control-Allow-Origin','*');
xhr.setRequestHeader('Access-Control-Allow-Methods','GET');
xhr.send();
}
I am running node js server on local_host:8888 and sending json response when accessed url like 'http://localhost:8888/systeminfo' .
And here is the json response that I am forming and sending from server
function GetSystemInfo(express)
{
express.namespace('/systeminfo', function(){
express.get('/', function(req, res){
var SYSTEM_INFO = 1;
var jsonres = '{\"event\" : [{ \"apiID\" : \"{0}\" }],\"data\":[{ \"manufacturerName\" : \"MNAME\",\"serialNo\" : \"123456\",}] }'.format(SYSTEM_INFO);
res.setHeader('Access-Control-Allow-Origin','*');
res.send(jsonres);
res.end();
});
});
}
Please Help.
Regards,
Techtotie.
Related
I am trying to sync both client-side and server-side scripts that the client intakes a value from the textbox and sends it to the server, upon which the server displays that input as a cookie.
Here is the code that I have so far
function loadCookie() {
//[1] make a new request object
var xhttp = new XMLHttpRequest();
//[2] set the request options
xhttp.open("GET", "index.html", true);
//[3] define what you will do when you ge a response (callback)
xhttp.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200) {
document.getElementById("input_response").innerHTML = this.responseText;
}
};
//[4] finally send out the request
xhttp.send();
}
I have the and the button but I am having issue of the page re-loading itself instead of taking the value of the input and showing it as a cookie in the server. I'm suspecting it is having to do with the URL by the index.html
So I have been working on this serverless configuration that calls a Lambda function through ajax. The I enable CORs through the API Gateway, and I have made sure of the domain I specified. This domain works when calling other lambda functions within the same API.
Now for the weird stuff.
I send a post request (I am trying to upload a file through ajax, lambda, and S3), to my API. If I configure the Access-Control-Allow-Origin so that it points to the domain WITHOUT the http in front of it. Ex: example.com. When I try to call this i get:
Failed to load https://m562ogkc1l.execute-api.us-east-1.amazonaws.com/test/upload: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'example.com' that is not equal to the supplied origin. Origin 'http://example.com' is therefore not allowed access.
Ok fine, this is assumed, since that's not the proper domain. So when I add in the http (http://example.com) for the CORs of the API I get:
Failed to load https://m562ogkc1l.execute-api.us-east-1.amazonaws.com/test/upload: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access. The response had HTTP status code 400.
What this seems like to me is that there is an issue elsewhere, except I don't know where the issue lies.
I have made sure the data I pass for parameters of the ajax call are strignified (JSON.stringify()), and I am NOT running an AWS Lambda Proxy which means I shouldn't be configuring responses on the lambda side of things.
This all really confuses me and I wish AWS had better documentation and examples since they really want to push these serverless services.
Further code is here:
Ajax:
$('#submitButton').on('click', function(){
//console.log(document.getElementById('fileUpload').value.substring(12));//C:\fakepath\ in front of filename (size = 12)
$.ajax({
type: 'POST',
url: 'https://m562ogkc1l.execute-api.us-east-1.amazonaws.com/test/upload',
data: JSON.stringify({"id": id,"name": document.getElementById('fileUpload').value.substring(12),"body": document.getElementById('fileUpload').files[0]}),
contentType: "application/json",
success: function(data){
console.log(data);
//location.reload();
}
});
return false;
});
Lambda:
const AWS = require('aws-sdk');
var s3 = new AWS.S3();
exports.handler = async (event) => {
let encodedImage = JSON.parse(event.body);
let decodedImage = Buffer.from(encodedImage, 'base64');
var filePath = event.id + '/' + event.name
var params = {
"Body": decodedImage,
"Bucket": "repository.example.com",
"Key": filePath
};
return await new Promise((resolve, reject) => {
s3.upload(params, function(err, data){
if(err) {
let response = {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "http://example.com"
},
"body": JSON.stringify(err),
"isBase64Encoded": false
};
resolve(response);
} else {
let response = {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "http://example.com"
},
"body": JSON.stringify(data),
"isBase64Encoded": false
};
resolve(response);
}
});
});
};
(Yes I threw in some response configuration for the function, I just wanted to see if it would work)
We're running an external Grails server-application with the Spring Security plugin.
The front-end is running locally on AngularJS.
Whenever I try to login, the request is immediately canceled.. Remarkably AngularJS sends a GET request first with the OPTIONS method; this returns a 200 OK response just fine.
The actual POST request does never reach the server though... what could possibly cancel my request?
The following code:
$scope.login = function() {
$http.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
$scope.loggingIn = true;
// Setup Config
var data = {
j_username: $scope.user.email,
j_password: $scope.user.password
}
var config = {method: 'POST', url: serverUri+'/j_spring_security_check/', data: data};
// Dispatch HTTP Request
$http(config)
.success(function(data, status, headers, config) {
if (data.status) {
// successful login
User.isLogged = true;
User.username = data.username;
}
else {
User.isLogged = false;
User.username = '';
}
$scope.loggingIn = false;
console.log("NOICE!");
})
.error(function(data, status, headers, config) {
$scope.loggingIn = false;
User.isLogged = false;
User.username = '';
if (status == 0) {
// Request got cancelled
console.log("Request got cancelled.");
return;
}
});
}
This is what the canceled request looks like: http://i.stack.imgur.com/kiWnb.png
This is what the OPTIONS request looks like: http://i.stack.imgur.com/FAj96.png
Apparently Chrome does not handle 302 Moved temporarily status codes efficiently when queried by AngularJS in my situation. Firefox properly shows there is a response where Chrome just shows the request as canceled with no response information whatsoever.
This question is solved, but there is still a mystery as to WHY AngularJS does not work. See my question here:
AngularJS $http ajax does not follow Location header
I want to send the filepath of a file on my server to the client in order to play it using a media player. How can I retrieve that string on the client side in order to concatenate it in the src attribute of a <video element without using sockets?
Server snippet:
res.set('content-type', 'text/plain');
res.send('/files/download.mp4');
This is how you make a request to the server without any frameworks. "/path_to_page" is the route you set to the page that is supposed to process the request.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path_to_page', true);
xhr.onload = function(e) {
if (this.status == 200) {
console.log(this.responseText); // output will be "/files/download.mp4"
}
};
xhr.send();
}
You might also want to send some params.
var formdata = new FormData();
formdata.append("param_name", "value");
So you might for instance want to send the filename or such.
You just need to change 2 lines from the first code snippet. One would be
xhr.open('POST', '/path_to_page', true); // set to post to send the params
xhr.send(formdata); // send the params
To get the params on the server, if you are using express, they are in req.body.param_name
Which framework are you using??
You can declare base path of your project directory in ajax and the followed by your file.
jQuery.ajax({
type: "GET",
url: "/files/download.mp4",
});
Since you are using express (on node), you could use socket.io:
Server:
var io = require('socket.io').listen(80),
fs = require('fs');
io.sockets.on('connection', function (socket) {
socket.on('download', function(req) {
fs.readFile(req.path, function (err, data) {
if (err) throw err;
socket.emit('video', { video: data });
});
});
});
Client:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
...
// request a download
socket.emit('download', { path: '/files/download.mp4' });
// receive a download
socket.on('video', function (data) {
// do sth with data.video;
});
...
</script>
Edit: didnt notice you didnt want to use sockets. Still it is a viable solution.
I have the following node.js server set up listening to port 9001
var https = require('https');
var fs = require('fs');
var qs = require('querystring');
var options = {
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
console.log('Request Received!');
console.log(req.method);
if (true || req.method == 'POST') {
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function () {
console.log(body);
var POST = qs.parse(body);
console.log(POST);
});
}
res.end("hello, world\n");
}).listen(9001);
and I am trying to get this server to respond to an AJAX call
function form_save()
{
console.log("submitted!");
var data_obj = {
data1: "item1",
data2: "item2"
}
$.ajax({
url: 'https://adam.testserver.com:9001/',
type: "POST",
dataType: "json",
data: data_obj,
success: function() {
console.log("success!");
},
complete: function() {
console.log("complete!");
}
});
}
There are two problems occurring with my arrangement. The first is that if I start the server and then click the button that triggers my form_save() the node server does not respond and I get the following error:
submitted!
OPTIONS https://adam.testserver.com:9001/ Resource failed to load
jQuery.extend.ajaxjquery.js:3633
$.ajaxjquery.validate.js:1087
form_savew_worksheet.php:64
confirm_deletew_worksheet.php:95
jQuery.event.handlejquery.js:2693
jQuery.event.add.handlejquery.js:2468
w_worksheet.php:73
complete!
At this point if I access that url directy (https://adam.testserver.com:9001/) I get the expected "hello, world" output as well as the console message "Request Received!
GET". From this point on if I click the button to trigger my AJAX call I get a new error.
submitted!
XMLHttpRequest cannot load https://adam.testserver.com:9001/. Origin
https://adam.testserver.com is not allowed by Access-Control-Allow-Origin.
w_worksheet.php:73
complete!
I don't understand why I get this message as both my form and node server reside on the same server. Thanks for taking the time to read, I appreciate any help I can get on this. I've been stuck for a while now!
You've run into the Cross-Origin Resource Sharing (CORS) specification.
Note the OPTIONS in your output. The OPTIONS HTTP Verb is used by the browser to query the web server about the URL, not to GET its contents or POST data to it.
Your server doesn't respond with the correct header data on a CORS request, so your browser assumes it has no rights to access the data, and refuses to GET or POST to the URL.
If you truly want to let any website in the world run that AJAX request, you can do something similar to the following:
function handleOptions(request, response) {
response.writeHead(200, {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Method": "POST, GET, OPTIONS",
"Access-Control-Allow-Headers": request.headers["access-control-request-headers"]
});
response.end();
}
function server(request, response) {
if(request.method == "POST") {
handlePost(request, response);
} else if(request.method == "OPTIONS") {
handleOptions(request, response);
} else {
handleOther(response);
}
}
https.createServer(sslObj, server).listen(9001);
You can fill in the details and whether you should handle GET separately, and so on (handleOther should return an appropriate error code for each request method you don't support).