I am trying to post using angular but keep getting a 404 error. It looks like the request is not being made. Any ideas why? Thanks for all the help.
var param = $scope.tag;
// client
$http({method: 'Post', url: '/api', headers: {
"Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }, data: {tag: param}})
.then(function(response) {
console.log(response);
});
// server
app.post('/api', function (req, res) {
var tag = req.body.tag;
request("http://food2fork.com/api/search?key=KEY&q=" + tag, function (req, res) {
res.json(response);
});
});
// request headers
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Connection:keep-alive
Content-Length:17
Content-Type:application/json
Host:localhost:3000
// response headers
Connection:keep-alive
Content-Length:22
Content-Type:text/html; charset=utf-8
Date:Sat, 19 Sep 2015 23:22:15 GMT
X-Content-Type-Options:nosniff
X-Powered-By:Express
You should not have to use all that code. Try:
// Client:
var tag = $scope.tag;
$http.post('/api', {tag: tag})
.then(function(response) {
console.log(response);
});
//Server:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/api', function(req, res) {
var tag = req.body.tag;
res.send(tag);
});
Use method: 'POST' instead of method:'Post'.
The latter is not recognized and a default GET is emitted instead that the POST you expect.
edit: checked the code and what I wrote above is not true
In addition to that...shouldn't be some URL like
/api/tags
???
Related
Node Server
var app = express();
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
}
});
React JS Fetch
function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON);
}
export function* login() {
const username = yield select(makeSelectUsername());
const password = yield select(makeSelectPassword());
const requestURL = 'http://myurlhere.com:1337/user/login/';
const requestOptions = {
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(
{username: username,
password: password}
)
}
try {
const result = yield call(request, requestURL, requestOptions);
yield put(loginApiCallSuccess(result));
} catch (err) {
yield put(loginApiCallFailure(err));
}
}
I need help determining what is wrong with my request or server side handling where chrome is cancelling my requests after preflight failure, aka why is my preflight request failing.
I am running the react on localhost and connecting to a remote server with a different url.
From what I can tell the preflight request is failing then chrome is cancelling the request. However when I ran the request locally the login was still hitting the login route on the node side successfully.
When stepping through the code I get a 400 error from the services on the actual call after the preflight call. If I run the call and don't step through I get a
(canceled) in the network tab of dev tools. However the call is successful on the server side each time.
General
Request URL:http://jenkins.murmillosoftware.com:1337/user/register/
Request Method:POST
Status Code:400 Bad Request
Remote Address:52.5.222.29:1337
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Origin
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:http://127.0.0.1:3000
Connection:keep-alive
Content-Length:47
Content-Type:application/json; charset=utf-8
Date:Wed, 16 Aug 2017 22:24:48 GMT
ETag:W/"2f-vn6Bxm14Gkpb5HFTCsgU2h3Nq3o"
set-cookie:connect.sid=s%3AjPVtqIoi6zy0QPmhfFkprFObfwj_J-Lw.sPvW3qRc1Vwj4R6qFBtW0oXykF68Qn%2FAwmLCWrg51qc; Path=/; HttpOnly
X-Powered-By:Express
Request Headers
view source
Accept:application/json
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:44
Content-Type:application/json
Host:jenkins.murmillosoftware.com:1337
Origin:http://127.0.0.1:3000
Pragma:no-cache
Referer:http://127.0.0.1:3000/login?
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Request Payload
view source
{username: "fdasfas", password: "asdfasdf"}
password
:
"asdfasdf"
username
:
"fdasfas"
have you ever tried express/cors i recently also had problem with access allow origin then i download express/cors from
npm install cors
then add in your program
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
you can also see other method to use cors in [link]https://github.com/expressjs/cors
I am using express js in backend and doing fetch in frontend. My frontend is hosted by webpack-dev-sever which is running locally on port 3000. My express js server is running locally on port 3001. I need to send some custom headers along-with my request.
My express js server is using 'morgan' for logging on terminal. The code of my server looks like this:
const express = require('express')
const bodyParser = require('body-parser')
const morgan = require('morgan')
const fs = require('fs')
const path = require('path')
const mime = require('mime')
const http = require('http')
const cors = require('cors')
const server = express();
let whitelist = [
'http://localhost:3000',
];
var corsOptions = {
origin: function(origin, callback){
var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
callback(null, originIsWhitelisted);
},
credentials: true
};
server.use(cors(corsOptions));
server.use(bodyParser());
server.use(morgan('dev'));
server.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type, x-imei, X-API-Key, requestId, Authorization');
res.header('Access-Control-Allow-Methods', '*');
next()
})
server.post('/verify/identifier', function(req, res, next) {
console.log(req.body)
console.log(req.headers)
res.send({"responseCode":"0012"});
});
server.listen(port, function() {
console.log(`server hosted on port ${port}`)
})
My frontend code is this:
export function fetchMerchantApi(url, body) {
let reqObj = {
method: 'POST',
headers: {
"Content-Type": "application/json",
"X-API-Key": secret_key,
"requestId": getUniqueId()
},
cache: 'default',
mode: 'cors'
}
try {
return new Promise((res, rej) => {
fetch(url, reqObj).then(result => {
return result.json()
}).then(data => {
res(data)
});
})
} catch(e) {
throw new Error(e);
}
}
fetchMerchantApi("http://localhost:3001/verify/identifier", reqBody).then(res => {
console.log(res);
})
All imports, syntax, etc are correct.
The chrome debugger tool's network tab is this:
The logs in terminal of server:
body
[0] { customField1: 'Y',
[0] imei: '358967064854480',
[0] isMerchantExist: 'Y',
[0] mobileNo: '9999999999',
[0] serialNumber: 'ZY22285JKV' }
headers:
[0] { host: 'localhost:3001',
[0] connection: 'keep-alive',
[0] 'content-length': '119',
[0] 'x-imei': '358967064854480',
[0] origin: 'http://localhost:3000',
[0] requestid: '9999999999300513303519185',
[0] 'content-type': 'application/json',
[0] 'user-agent': 'Mozilla/5.0 (Linux; Android
6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Mobile Safari/537.36',
[0] 'x-api-key': 'l7xx5a9a4eea46054ef38b18b5e6fdbd2c5a',
[0] accept: '/',
[0] referer: 'http://localhost:3000/auth/verifyNo',
[0] 'accept-encoding': 'gzip, deflate, br',
[0] 'accept-language': 'en-IN,en-GB;q=0.8,en-US;q=0.6,en;q=0.4' }
morgain log:
[0] POST /cr/v2/merchant/verify/identifier 200 2.432 ms - 23
After all this, I am getting no error and also no response data from backend.
Funny thing is that my rest client(Postman) works fine. I get data on postman.
This is a tricky one . It is an options request, that is a preflight request from the browser. The options request contains two http headers Access-Control-Request-Headers' andAccess-Control-Method` .
But it looks like you allowing every method in cors options.
you can enable pre flight requests like
app.options('*', cors())
i want to upload image using Angularjs anyone know how do this..REST API wants
Content-Type:multipart/form-data
www.abc.com/images/id
Request Body
{
// --Boundary_1_1626119499_1392398808202
// Content-Type: image/png
// Content-Disposition: form-data; filename="ducky.png"; modification-date="Wed, 05 Nov 2016 19:53:17 GMT"; size=713915; name="upload_image"
// {binary data truncated for display}
}
my Question is how to upload image file using above rest API, how to assign $scope.tempObject = my Upload image Path
$scope.UploadImage = function () {
var config = {headers: {
'Content-Type': 'multipart/form-data'
}
}
$http.post(properties.customerUploadImage_path + "/"+checkprofile,$scope.tempObject,config).success(function (response) {
Console.log('Uploaded');
});
}
I think you don't use $http the right way.
You can use the headers attribute of the $http service, like this :
$scope.UploadImage = function () {
var config = {
headers: {
'Content-Type': 'multipart/form-data',
}
};
$http({
method: 'POST',
url: properties.customerUploadImage_path + "/" + checkprofile,
data: $scope.tempObject,
config: config,
}).success(function (response) {
console.log('Uploaded');
});
};
I suggest you to take a look at the documentation.
Configure the headers with "Content-Type": undefined and use the FormData API:
var config = { headers: {
"Content-Type": undefined,
}
};
vm.upload = function() {
var formData = new $window.FormData();
formData.append("file-0", vm.files[0]);
$http.post(url, formData, config).
then(function(response) {
vm.result = "SUCCESS";
}).catch(function(response) {
vm.result = "ERROR "+response.status;
});
};
Normally the AngularJS $http service uses Content-Type: application/json. By setting Content-Type: undefined, the framework will omit the Content-Type header and the browser will use its default content type which is multipart/form-data for FormData objects.
Request Header
POST /post HTTP/1.1
Host: httpbin.org
Connection: keep-alive
Content-Length: 388298
Accept: application/json, text/plain, */*
Origin: https://run.plnkr.co
User-Agent: Mozilla/5.0 Chrome/55.0.2883.54 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9lBDT4yoh8lKWtIH
Referer: https://run.plnkr.co/cW228poRVzWs67bT/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Request Payload
------WebKitFormBoundary9lBDT4yoh8lKWtIH
Content-Disposition: form-data; name="file-0"; filename="Crop.jpg"
Content-Type: image/jpeg
------WebKitFormBoundary9lBDT4yoh8lKWtIH--
The DEMO on PLNKR.
For more information see,
AngularJS $http Service API Reference -- Setting HTTP Headers
MDN Documents -- FormData API
I was trying to make a simple request to site. it should get html text, but it gets ' '
NPM module here: github.com/request/request
Code:
var fs = require('fs');
var request = require('request');
var options = {
url:'https://sample.site/phpLoaders/getInventory/getInventory.php',
encoding : 'utf8',
gzip : true,
forever: true,
headers: {
'Host': 'sample.site',
'Connection': 'keep-alive',
'Content-Length': '58',
'Cache-Control': 'max-age=0',
'Accept': '*/*',
'Origin': 'https://csgosell.com',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'https://sample.site/',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
'Cookie': 'my-cookies from browser'
},
form: {
stage:'bot',
steamId:76561198284997423,
hasBonus:false,
coins:0
}
};
request.post(options,
function(error, response, body){
console.log(response.statusCode);
if (!error) {
fs.writeFileSync('site.html', body);
}
else{
console.log(error);
}
}
);
Chrome request: https://i.stack.imgur.com/zKQo5.png
Nodejs request:https://i.stack.imgur.com/yH9U3.png
the difference is in headers:
:authority:csgosell.com
:method:POST :path:/phpLoaders/getInventory/getInventory.php :scheme:https
after some googling, I anderstood that it is http2, and tried to put it inow another agent's options, but nothing changed.
var spdy = require('spdy');
var agent = spdy.createAgent({
host: 'sample.site',
port: 443,
spdy: {
ssl: true,
}
}).once('error', function (err) {
this.emit(err);
});
options.agent = agent;
To answer your question i will copy/paste a part of my code that enable you to receive a post request from your frontend application(angularJS) to your backend application (NodeJS), and another function that enable you to do the inverse send a post request from nodeJS to another application (that might consume it):
1) receive a request send from angularJS or whatever inside your nodeJS app
//Import the necessary libraries/declare the necessary objects
var express = require("express");
var myParser = require("body-parser");
var app = express();
// we will need the following imports for the inverse operation
var https = require('https')
var querystring = require('querystring')
// we need these variables for the post request:
var Vorname ;
var Name ;
var e_mail ;
var Strasse ;
app.use(myParser.urlencoded({extended : true}));
// the post request is send from http://localhost:8080/yourpath
app.post("/yourpath", function(request, response ) {
// test the post request
if (!request.body) return res.sendStatus(400);
// fill the variables with the user data
Vorname =request.body.Vorname;
Name =request.body.Name;
e_mail =request.body.e_mail;
Strasse =request.body.Strasse;
response.status(200).send(request.body.title);
});
2) Do the inverse send a POST request from a nodeJS application to another application
function sendPostRequest()
{
// prepare the data that we are going to send to anymotion
var jsonData = querystring.stringify({
"Land": "Land",
"Vorname": "Vorname",
"Name": "Name",
"Strasse": Strasse,
});
var post_options = {
host: 'achref.gassoumi.de',
port: '443',
method: 'POST',
path: '/api/mAPI',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': jsonData.length
}
};
// request object
var post_req = https.request(post_options, function(res) {
var result = '';
res.on('data', function (chunk) {
result += chunk;
console.log(result);
});
res.on('end', function () {
// show the result in the console : the thrown result in response of our post request
console.log(result);
});
res.on('error', function (err) {
// show possible error while receiving the result of our post request
console.log(err);
})
});
post_req.on('error', function (err) {
// show error if the post request is not succeed
console.log(err);
});
// post the data
post_req.write(jsonData);
post_req.end();
// ps : I used a https post request , you could use http if you want but you have to change the imported library and some stuffs in the code
}
So finally , I hope this answer will helps anyone who is looking on how to get a post request in node JS and how to send a Post request from nodeJS application.
For further details about how to receive a post request please read the npm documentation for body-parser library : npm official website documentation
Whenever I make a webapp and I get a CORS problem, I start making coffee. After screwing with it for a while I manage to get it working but this time it's not and I need help.
Here is the client side code:
$http({method: 'GET', url: 'http://localhost:3000/api/symbol/junk',
headers:{
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With',
'X-Random-Shit':'123123123'
}})
.success(function(d){ console.log( "yay" ); })
.error(function(d){ console.log( "nope" ); });
The server side is a regular node.js with an express app. I have an extention called cors and it's being used with express this way:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
app.use(cors({origin:"*"}));
});
app.listen(3000);
app.get('/', function(req, res){
res.end("ok");
});
If I do
curl -v -H "Origin: https://github.com" http://localhost:3000/
It gets back with:
* Adding handle: conn: 0x7ff991800000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7ff991800000) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3000 (#0)
* Trying ::1...
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3000
> Accept: */*
> Origin: https://github.com
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Date: Tue, 24 Dec 2013 03:23:40 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
ok
If I run the client side code, it brigs up this error:
OPTIONS http://localhost:3000/api/symbol/junk No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. angular.js:7889
XMLHttpRequest cannot load http://localhost:3000/api/symbol/junk. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. localhost/:1
nope
Checking Chromes headers:
Request URL:http://localhost:3000/api/symbol/junk
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4
Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-methods, access-control-allow-headers, x-random-shit
Access-Control-Request-Method:GET
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Response Headersview source
Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
Date:Tue, 24 Dec 2013 03:27:45 GMT
X-Powered-By:Express
Checking the request headers I see that my test string X-Random-Shit is present in the "Access-Control-Request-Headers" but it's value is not there. Also, in my head I was expecting to see one line for each one of the headers I am setting, not a blob.
UPDATES ---
I changed my frontend to jQuery instead of Angular and made my backend like this:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
});
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,DELETE');
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
if ('OPTIONS' == req.method){
return res.send(200);
}
next();
});
app.get('/', function(req, res){
res.end("ok");
});
Now it works with GET but does not with anything else (PUT, POST..).
I'll see if any of you comes up with a solution. In the mean time in throwing the RESTful concept out the window and making everything with GETs.
I'm new to AngularJS and I came across this CORS problem, almost lost my mind! Luckily i found a way to fix this. So here it goes....
My problem was, when I use AngularJS $resource in sending API requests I'm getting this error message XMLHttpRequest cannot load http://website.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. Yup, I already added callback="JSON_CALLBACK" and it didn't work.
What I did to fix it the problem, instead of using GET method or resorting to $http.get, I've used JSONP. Just replace GET method with JSONP and change the api response format to JSONP as well.
myApp.factory('myFactory', ['$resource', function($resource) {
return $resource( 'http://website.com/api/:apiMethod',
{ callback: "JSON_CALLBACK", format:'jsonp' },
{
method1: {
method: 'JSONP',
params: {
apiMethod: 'hello world'
}
},
method2: {
method: 'JSONP',
params: {
apiMethod: 'hey ho!'
}
}
} );
}]);
I hope someone find this helpful. :)
I've had success with express and editing the res.header. Mine matches yours pretty closely but I have a different Allow-Headers as noted below:
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
I'm also using Angular and Node/Express, but I don't have the headers called out in the Angular code only the node/express
Writing this middleware might help !
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();
});
for details visit http://enable-cors.org/server_expressjs.html
Adding below to server.js resolved mine
server.post('/your-rest-endpt/*', function(req,res){
console.log('');
console.log('req.url: '+req.url);
console.log('req.headers: ');
console.dir(req.headers);
console.log('req.body: ');
console.dir(req.body);
var options = {
host: 'restAPI-IP' + ':' + '8080'
, protocol: 'http'
, pathname: 'your-rest-endpt/'
};
console.log('options: ');
console.dir(options);
var reqUrl = url.format(options);
console.log("Forward URL: "+reqUrl);
var parsedUrl = url.parse(req.url, true);
console.log('parsedUrl: ');
console.dir(parsedUrl);
var queryParams = parsedUrl.query;
var path = parsedUrl.path;
var substr = path.substring(path.lastIndexOf("rest/"));
console.log('substr: ');
console.dir(substr);
reqUrl += substr;
console.log("Final Forward URL: "+reqUrl);
var newHeaders = {
};
//Deep-copy it, clone it, but not point to me in shallow way...
for (var headerKey in req.headers) {
newHeaders[headerKey] = req.headers[headerKey];
};
var newBody = (req.body == null || req.body == undefined ? {} : req.body);
if (newHeaders['Content-type'] == null
|| newHeaders['Content-type'] == undefined) {
newHeaders['Content-type'] = 'application/json';
newBody = JSON.stringify(newBody);
}
var requestOptions = {
headers: {
'Content-type': 'application/json'
}
,body: newBody
,method: 'POST'
};
console.log("server.js : routes to URL : "+ reqUrl);
request(reqUrl, requestOptions, function(error, response, body){
if(error) {
console.log('The error from Tomcat is --> ' + error.toString());
console.dir(error);
//return false;
}
if (response.statusCode != null
&& response.statusCode != undefined
&& response.headers != null
&& response.headers != undefined) {
res.writeHead(response.statusCode, response.headers);
} else {
//404 Not Found
res.writeHead(404);
}
if (body != null
&& body != undefined) {
res.write(body);
}
res.end();
});
});
#Swapnil Niwane
I was able to solve this issue by calling an ajax request and formatting the data to 'jsonp'.
$.ajax({
method: 'GET',
url: url,
defaultHeaders: {
'Content-Type': 'application/json',
"Access-Control-Allow-Origin": "*",
'Accept': 'application/json'
},
dataType: 'jsonp',
success: function (response) {
console.log("success ");
console.log(response);
},
error: function (xhr) {
console.log("error ");
console.log(xhr);
}
});
I have found a way to use JSONP method in $http directly and with support of params in the config object:
params = {
'a': b,
'callback': 'JSON_CALLBACK'
};
$http({
url: url,
method: 'JSONP',
params: params
})
Try with this:
$.ajax({
type: 'POST',
url: URL,
defaultHeaders: {
'Content-Type': 'application/json',
"Access-Control-Allow-Origin": "*",
'Accept': 'application/json'
},
data: obj,
dataType: 'json',
success: function (response) {
// BindTableData();
console.log("success ");
alert(response);
},
error: function (xhr) {
console.log("error ");
console.log(xhr);
}
});