I'm currently developing a web application using AngularJS on the fronted and NodeJS on the backend with express. I've had trouble requesting my backend API from the fronted however and hope you guys can help me.
Backend (NodeJS):
app.get('/test', function(req, res) {
res.json(200, {'test': 'it works!'})
})
Frontend (AngularJS):
myApp.controller('myController', function($scope, $http) {
delete $httpProvider.defaults.headers.common["X-Requested-With"]
$http.get('http://localhost:5000/test').success(function(data) {
alert('Success')
}).error(function(data, status) {
alert('Error! ' + status + ' : ' + data)
})
})
When I refresh the app I get an alert saying: Error! 0 :, however, when I request the backend with curl or by the browser, I get the test dict back. The frontend seems to be able to access the backend though because I see it in my backend log that it's done a request and got something back, but firebug says that the response is empty, what should I do?
Thanks so much, let me know if you need more info from me.
Mattias
Make sure that your frontend and backend servers have the same origin (protocol, host and port). If not, then you does not recieve response since you make cross-origin ajax request. In this case you should send special header from your backend to allow it:
Access-Control-Allow-Origin: *
You can add response header with the following code:
res.set('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Origin', '*');
Use res.status(status).json(obj) instead of res.json(status, obj)
Related
I have two servers, frontend (Next.js) and backend (express.js api server).
Frontend server is running without any additions. But I have an nginx proxy for backend.
So far everything is good because they are not connected yet.
Frontend: is working as it should be.
Backend: I can make calls directly from the backend itself (by self origin).
When I make a fetch get call from my frontend server to the backend server, it normally gives a cors error because the origins are different.
For this, I set the backend server with cors:
// /src/middlewares/cors.ts
import cors from 'cors';
const whitelist = new Set(['http://192.168.1.106:3000', 'https://192.168.148.132']);
// frontend: http://192.168.1.106:3000
// backend: https://192.168.148.132
const corsOptions = {
optionsSuccessStatus: 200,
origin: (origin: any, callback: any) => {
console.log('origin: ' + origin);
if (whitelist.has(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
// credentials: true,
};
export default cors(corsOptions);
and
// /app.ts
import cors from './middlewares/system/cors.js';
.
.
// setup cors
app.options('*', cors);
app.use(cors);
.
.
After doing this, I reach my main goal. The frontend server can make call to the backend server.
output:
But this time I notice a problem. I can't send self request to backend anymore (by self origin).
When dealing with this I looked at the origins that came to the /src/middlewares/cors.ts file that I showed above.
for frontend:
for backend:
I am using self signed ssl in nginx for back server.
And there is not any cors relevant headers in conf.
How can i solve this situation?
(If I'm missing something, you can point it out in the comments.)
The Origin header is only set in cross-origin requests. If you call your backend directly, the Javascript value is undefined, and in this case you must not restrict anything. You could, for example, write
if (!origin || whitelist.has(origin)) {
callback(null, true);
}
I've a AngularFullStack project in which I'm trying to hit my project's server endpoint using the following code, however the problem is the call isn't going through from angular client side to the nodejs server. Since it's my first project, I've little to no idea what might be going wrong that might be causing this weird conflict.
ClientSide:
$http({
method: 'POST',
url: '/api/soapAPIs/soapAPI',
data: request,
headers: {
'Content-Type': 'application/json'
}
})
.then(function(response) {
console.log("response from server is: ", response);
})
.catch(function(error) {
console.log("error in calling server is: ", error);
});
I have installed CORS on server side and wrote the following code in app.js but still it doesn't work.
Server App.js
// Setup server
var app = express();
var cors = require('cors');
//add cors to do the cross site requests
app.use(cors());
Server Endpoint Code:
export function soapAPI(req, res) {
console.log("SERVER SIDE ", req.body);
res.status(statusCode).json({"status":"success"});
res.send();
}
Following are the problems:
If I try to hit nodejs endpoint like this /api/soapAPIs/soapAPI, the browser shows pending request and it never goes to the server.
When I add the full classified url for the endpoint like this http:localhost:9000/api/soapAPIs/soapAPI, it hits the endpoint but then the client never receives response from the server. I don't want to provide the full classified URL on the client side for obvious reasons.
How can I resolve this issue? Please let me know if you need any other code/information.
EDIT:
By using full classified path, the server endpoint gets hit but its response is never received by the client side. I get this error in browser:
Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"/api/things","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":""}
Uncomment the following line:
/*mongoose.connect(config.mongo.uri, config.mongo.options);
mongoose.connection.on('error', function(err) {
console.error(`MongoDB connection error: ${err}`);
process.exit(-1); // eslint-disable-line no-process-exit
});
*/
Basically this is causing your controller to not return any response because your mongoose models are being referenced but the connection to mongo fails.
I have a node.js/express webservice that I would like to use to verify Google token coming from a mobile app.
From this tutorial (https://developers.google.com/identity/sign-in/android/backend-auth) I learned that I have to make such a call:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
So I came up with this in my code:
var request = require('request');
module.exports = function(app) {
app.get('/authenticate', function(req, res) {
request('https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
}
})
});
};
Then, based on the response from google api, I would like to return true or false.
But it doesn't work. When I put "https://www.google.com" in the request, body is printed in the console, but the request is still being executed for some time.
What am I missing here? Is is the correct approach to the problem I described or should I do it in a completely different way?
You need to send a response to your incoming HTTP request.
Call res.send(...).
For more information, see the Express documentation.
I'm trying to create a custom module for a deployd backend to authenticate with the instagram api. The code is as follows:
var request = require('request');
var payload = undefined;
process.server.on('request', function(req, res) {
if (req.url === '/foo') {
function getPayload(callback) {
var code = req.headers.referer.substr(req.headers.referer.lastIndexOf('/') + 1);
request.post('https://api.instagram.com/oauth/access_token', {form:{
client_id: '****',
client_secret: '****',
grant_type: 'authorization_code',
redirect_uri: 'http://localhost:2403/auth/auth.html',
code: code
}},
function(error, response, body) {
var payload = JSON.stringify(body);
console.log(payload);
callback();
});
}
function setPayload() {
res.end(payload);
}
getPayload(setPayload);
}
});
I can console.log the response from the instagram server, but then when I try to write the response back to the client I get a 404 response. What am I missing? Sorry if this is a total noob question. That would be because I'm a noob. Thanks in advance.
Sorry for the lack of clarity. Edit for more info: I'm creating an endpoint at /foo with the above code. The client sends a GET request to /foo from a referring URL containing the Instagram access code. The server then POSTs the access code along with the other app-specific parameters to the Instagram server which returns an object containing an authorization token and information about the user. The 404 comes at the point where the client GETs /foo. My code successfully sends the access code to the Instagram server and returns the object containing the access token - this outputs on the console - but it won't write it back to the client, and the client gets a 404. Also, the 404 is returned to the client before the object returned by the Instagram server is logged in the console.
I'm using a node.js server and need to post data over an http*s* protocol.
POST is listed as a http protocol, so I'm wondering if I'm on the wrong track.
Anyway, here is the top of my code that handles the POST. I've not included the on('end') function for berevity, but it is there.
exports.login = function(req, res){
if(req.method == 'POST'){
var datastring = '';
req.on('data', function(data){
datastring += data;
console.log("getting data");
if(datastring.length > 1e6){
req.connection.destroy();
}
});
Through console logs I can determine that the request is being made, and that the request is recognised as POST, but that req.on('data')'s function is never called.
I looked into a CONNECT protocol, but this isn't supported by browser forms - please advise how to send data through CONNECT if you don't think I can send POST data over HTTPS
Thanks for your help
EDIT: here is form that sends request:
<form name="loginForm" action="login" method="POST" onsubmit="return checkForm()" class="separate-sections">
and here is node.js code that grabs post
var app= express();
...
app.post('/login', route_login.login);
To make a long story short, does POST work over HTTPS? It doesn't seem to be working here.
Found out someone on my team had added the express bodyparser, so naturally posts no longer work in the way I had before. The change just happened to coincide with when we switched to https which made it look as if this was the issue, when it was not.