Get Same response in node as coming from angular - angularjs

I am developin app in angularjs and nodejs. I want to upload the image using angular and node. Image is sern dusing multipart/form-data. when i send data post request looks like:
{name="customer.pen.13", email="temp#temp.com", website="http://www.tels-tra.com,image:FileList { 0=File, length=1, item=item()}}
I want to get same format in nodejs.But in my node js I got:
{name="customer.pen.13", email="temp#temp.com", website="http://www.tels-tra.com}
Image is missing in request.
Here is my code:
exports.updateExchangeSetup = function(req, res, next) {
var request = require('request');
console.log(req);
console.log(req.body);
}
var headers = {
'headers': {
'User-Agent': 'Super Agent/0.0.1',
'Authorization': 'test',
'Access-Control-Allow-Methods': 'POST, GET, PUT, DELETE, OPTIONS',
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept,Authorization",
'Content-Type': 'application/json'
}
}

As per very short description from you code snippets, I am assuming you are using expressJS on the server side, could you please check the content-type you are handling on express side. I think its application/JSON, and it makes your app disable to understand multipart form data. However I need more details on nodeJs side to answer better.

Everything looks okay as per your snippets. Are you putting your image data on URL?
"http://www.tels-tra.com,image:FileList { 0=File, length=1, item=item()}}"
if this is a string, then it should not get tempered.
Instead of your snippet you could try the following example to upload image and sending other parameters. Maybe this is not the exact solution you are looking for, but it may give you an idea if you are dealing with file upload with extra parameters.
Use ngFileUploadat angular to upload file
Upload.upload({
url: "/api/enpoint/resources",
data: {file: filePath, 'name': "customer.pen.13", 'email'="temp#temp.com"},
headers: {/* your header object here */}
}).then(function (res) {
// do something
});
Node/ExpressJS router
use connect-multiparty middleware to intercept file
var multipartyMiddleware = require('connect-multiparty')();
router.post('/api/enpoint/resources',multipartyMiddleware, ctrl.updateExchangeSetup);
Node/ExpressJS Controller
exports.updateExchangeSetup = function(req, res, next) {
// files will be at: req.files
var imageFile = req.files.file;
var email = req.body.email
}

Related

Problem with CORS on React and PUT Ajax PUT request

I have an issue with my app. I use Express/node for the API and try to access it with React which works fine with Axios.
now I tried a DevExpress grid component to display data. fetching data is working fine but if I want to edit and save I get always a CORS error.
My settings on express:
app.use(
cors({
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
})
);
The API looks like this:
router.put('/dataToEdit', auth, (req, res) => {
MasterData.updateData(req, res);
});
If I want to call and bind to the grid:
const dataSource = createStore({
key: 'helperboxTypeId',
loadUrl: `${url}/getAlldataToEdit`,
insertUrl: `${url}/dataToEdit`,
updateUrl: `${url}/dataToEdit`,
deleteUrl: `${url}/dataToEdit`,
onBeforeSend: (method, ajaxOptions) => {
ajaxOptions.headers = {
'Content-Type': 'application/json',
'x-auth-token': localStorage.token,
};
ajaxOptions.crossDomain = true;
},
});
I tried it I think with every possible constellation of settings and I'm searching for about 1 day in several forums before I asked this :)
maybe somebody is using the same component and can help somehow.
the error is:
Access to XMLHttpRequest at 'http://localhost:5000/api/masterData/dataToEdit' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Another solution could be that I use Axios there but was not able to integrate it.
Many thanks in advance!
You should allow Access-Control-Allow-Origin as following:
app.all('/*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
Finally i found it thanks for the eye opener comments :)
the problem was that i missed at the top of the backend server.js a line i added weeks ago...
app.get('/', (req, res) => res.send(text.SERVER_API_RUNNING));
and seems if i add the cors setting then it works only for a part of my API's.

How to make get request to aws Api using React js

I have make request to aws api with get method using React js But it shows error :-
"Access to fetch at 'https://blahblah.com/dev/getControllist' from origin 'http://test.com:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response."
But If I hit same api direct to browser or using postman it returns json successfully. Please help me if anyone knows.
My code is:-
var uri = "blahblah.com/dev/getControllist";
let h = new Headers({
'Access-Control-Allow-Origin': '*',
"Access-Control-Allow-Credentials": true,
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
"Access-Control-Request-Headers": "Origin, X-Requested-With, Content-Type, Accept,x-access-token"
});
let request = new Request(uri,
{
method: 'GET',
headers: h,
cors:true
});
fetch(request)
.then((result) => {
// Get the result
// If we want text, call result.text()
return result.json();
}).then((jsonResult) => {
// Do something with the result
console.log(jsonResult);
this.setState({
items: jsonResult
});

angularjs malforms json while sending data to the server using POST

I have a Nodejs express server and an angularJs client which sends data to the server.
The problem is when I try to send a JSON to the server with angularJS, the received JSON becomes like this:
{"{\"question\":\"What will be result of code int a ":" 5/2\",\"answers\":[{\"a\":\"2.50\",\"b\":\"1\",\"c\":\"2\",\"d\":\"no right answer\"}],\"answer\":\"c\",\"score\":\"100\"}"}
Here is my post method in angularJS:
createQuestion: function(question){
delete question["_id"];
console.log(JSON.stringify(question))
return $http.post('http://localhost:3000/questions/', question, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.then(
function(response){
return response.data;
},
function(errResponse){
console.error('Error while creating question');
return $q.reject(errResponse);
}
);
}
the output of console.log(JSON.stringify(question)) is:
{"question":"What will be result of code int a = 5/2","answers":[{"a":"2.50","b":"1","c":"2","d":"no right answer"}],"answer":"c","score":"100"}
Here is the part of the code in nodejs responsible for POST methods:
exports.create_a_question = function(req, res) {
console.log(JSON.stringify(req.body))
var new_question = new Question(req.body);
new_question.save(function(err, question) {
if (err)
res.send(err);
res.json(question);
});
};
After a search I found out that this problem happens because of application/x-www-form-urlencoded in the header of requests but I add this configuration to my nodejs server and the problem still persists:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
Here is CORS headers on nodejs server:
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Max-Ag', '3600');
How can I solve the problem?
The back slashes ("\") happen when JSON.stringify is called twice:
var x = {a:1, b:2};
var y1 = JSON.stringify(x);
var y2 = JSON.stringify(y1);
console.log(y2);
The AngularJS framework automatically does a JSON.stringify with the $http.post method. The second JSON.stringify was called in the Node.js code.
The solution is to use JSON.parse in the Node.js code:
var x = {a:1, b:2};
var y1 = JSON.stringify(x);
var y2 = JSON.parse(y1);
console.log(y2);
So here is how I solved the problem:
download the cors library via npm:
npm install --save cors
use it in the code:
var cors = require('cors');
app.use(cors());
then I removed the unnecessary header option when calling angularjs $http.post
Possibly:
headers: { 'Content-Type': 'multipart/form-data', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache'}
Since there are multiple content types at issue here ...

How to send both data and header to a server?

I want to send a header to a server using http call POST request.
When I send the header only, everything is ok.
but when I add some data to the call, I get an error:
http://localhost:3000/test_post.
Request header field Content-Type is not
allowed by Access-Control-Allow-Headers in preflight response.
I use node.js as the server side language, this is the code for the CORS settings:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Expose-Headers", "x-auth");
res.header("Access-Control-Allow-Headers", "x-auth");
next();
});
This is the $http call with angular:
$http({
method: 'POST',
data: {name: 'Dani'},
url: 'http://localhost:3000/test_post'
headers: {
'x-auth': 'some token'
}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
console.log('error');
});
I know problem is about the CORS, but I don't know what to modify there,
If I remove res.header("Access-Control-Allow-Headers", "x-auth"); from the CORS I can get the data on the server but not the Header.
How can I get them both?
Hope you can help me with that, Thank you.

No 'Access-Control-Allow-Origin' header is present on the requested resource.

I've seen several questions and answers around this and mine is half working.
I have a node.js api server with url api.domain.com and the website on an nginx server at www.domain.com when I do the following in angular the request goes through on the api server, I see the request I see it getting parsed and put into the database. However, on the client side I do not get a return right away and then eventually I will see No 'Access-Control-Allow-Origin' header is present on the requested resource.
I know what is causing this behavior but shouldn't it throw the error before it hits the API server? Also note that the node.js server has cors enabled. The response that should be coming back is json.
$http({
method: 'POST',
url: "http://api.domain.com/addtrans/" + $scope.accountID,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT',
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {
payload: JSON.stringify(trans)
}
}).success(function (result) {
$scope.trans = {};
console.log(result);
});
I have used the below middleware for all of our projects and it has been proven to work best.
const allowCors = (req, res, next) => {
/** Allow all origins, for now TODO */
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', 'Authorization, Content-Type');
res.header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
/** Browser check for pre-flight request to determine whether the server is webdav compatible */
if ('OPTIONS' == req.method) {
res.sendStatus(204);
}
else next();
};
// Put this code before the routes you want to allow CORS to
app.use(allowCors);
You should change the Allow-Origin to something more restricted for security reasons.
The above code covers CORS as well as pre-flight on most browsers(this ia major issue we were having in the beginning).
i used this a while ago (express 3.x):
// npm install --save cors
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
app.use(express.static());
app.get('*', function(){});
require('http').createServer(app).listen(3000)
Remember that the cors header should be on the response which is coming from server not the request which is sent from client.
You can use a middleware to enable cors on the server:
//CORS middleware
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'example.com');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
//...
app.configure(function() {
...
app.use(allowCrossDomain);
...
});

Resources