18

I want to send an HTTP POST request by submitting a form to my server, which is located at a different domain (enabled cors in the server script using node.js).

This is the script where all the Angular configurations are :

var myApp = angular.module('myApp', ['ngRoute']);

myApp.config(function($routeProvider, $locationProvider, $httpProvider) {

  $httpProvider.defaults.useXDomain = true;
  delete $httpProvider.defaults.headers.common['X-Requested-With'];

  $routeProvider
  .when('/', {
    controller: 'RouteCtrl',
    templateUrl: 'views/home_views.html'
  })
  .when('/login', {
    controller: 'RouteCtrl',
    templateUrl: 'views/login_views.html'
  })
  .when('/register', {
    controller: 'RouteCtrl',
    templateUrl: 'views/register_views.html'
  })
});

myApp.controller("UserController", function($scope, $http) {
  $scope.formData = {};
  $scope.clickMe = function() {
    console.log("Yay");
      $http({
        method: 'POST',
        url: 'http://localhost:8183/user/register',
        data: $.param($scope.formData),
      })
      .success(function(data) {
        console.log(data);
        if(!data.success) {
          console.log("error here");
        } else {
          console.log("error there");
        }
      });
  }
}); ...

I'm using AngularJS 1.2.22 and as it stated in this tutorial (Enable CORS) to enable CORS, it needs to enable CORS manually in the config. But it's still not working. Here is what I got from the browser console.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8183/user/register. This can be fixed by moving the resource to the same domain or enabling CORS.

I'm quite new to AngularJS so any help would really be appreciated to point out any mistakes I made.. Thank you!

---- EDIT : Adding server.js script ----

var express = require('express'),
    app = express(),
    bodyParser = require('body-parser'),
    expressValidator = require('express-validator'),
    mysql = require('mysql'),
    crypto = require('crypto'),
    cors = require('cors'),
    uuid = require('node-uuid');

var connectionpool = mysql.createPool({
    connectionLimit: 1000,
    host: 'localhost',
    user: 'root',
    password: '',
    database: 'cloudvm'
});

app.listen(8183);
app.use(bodyParser.urlencoded({
    extended: true
}));

app.use(bodyParser.json());
app.use(expressValidator());
app.use(cors());


var user_router = express.Router();
var user_list = user_router.route('/list');
var user_register = user_router.route('/register');
var user_login = user_router.route('/login');

app.use('/user', user_router);

user_register.post(function(req, res, next) {

    var errors = req.validationErrors();
    if (errors) {
        res.status(200);
        res.send(errors);
        console.log(errors);
        return;
    }
    var data = {
        name_user: req.body.name,
        email_user: req.body.email,
        password_user: req.body.password,
        no_telp_user: req.body.no_telp,
        company_name_user: req.body.company_name,
        address_user: req.body.address,
        name_cc_user: req.body.name_cc,
        address_cc_user: req.body.address_cc,
        no_cc_user: req.body.no_cc,
        no_vcv_user: req.body.no_vcv,
        expire_month_cc_user: req.body.expire_month,
        expire_year_cc_user: req.body.expire_year
    };

    connectionpool.getConnection(function(err, connection) {
        if (err) {
            console.error('CONNECTION ERROR:', err);
            res.statusCode = 503;
            res.send({
                result: 'error',
                err: err.code
            });
        } else {
            var sql = 'INSERT INTO user SET ?';
            console.log(sql)
            connection.query(sql, data, function(err, rows, fields) {
                if (err) {
                    console.error(err);
                    res.statuscode = 500;
                    res.send({
                        result: 'error',
                        err: err.code
                    });
                }
                res.send([{
                    msg: "registration succeed"
                }]);
                connection.release();
            });

        }

    });
});

SOLUTION

Thank you for the kind answers, but I've managed to enable CORS on my server script (running on Node) then I tried to use this

headers: { 'Content-Type': 'application/x-www-form-urlencoded' }

on my client-side script when the http request is called, then it finally let me to get response from the server without having the CORS problem! So, I thought it might be the header problem .. So, thank you for kind responses! Hope this would help anyone having this problem in the future!

georgeawg
  • 48,608
  • 13
  • 72
  • 95
prameshvari
  • 241
  • 1
  • 3
  • 11
  • 1
    CORS has to be enabled by the target resource not angularjs – Arun P Johny Apr 28 '15 at 09:36
  • *and enabled cors in the server script using node.js* — There error message you are getting says you haven't done that correctly. – Quentin Apr 28 '15 at 09:37
  • hi @Quentin, thank you for responding to my question, I added the server script. would you mind to help checking it if there's anything wrong? thank you! – prameshvari Apr 28 '15 at 09:54
  • Did `var cors = require('cors') var app = express() app.use(cors())` to enable it.. is it not quite right? – prameshvari Apr 28 '15 at 10:04
  • When you get a CORS error, it usually means you're trying to access content from a server different to the one the site is hosted. If your DB is located in a VPS and your angular content is hosted on your localhost, you will be limited by CORS rules. So, you either turn off CORS on your VPS or move the server over to the same location as your angular code. – Bwaxxlo Apr 28 '15 at 10:04
  • Thanks for posting the solution. +1 – user2085143 Jan 21 '16 at 17:58
  • @ArunPJohny then why this error occurs? **No 'Access-Control-Allow-Origin' header is present on the requested resource.** – MaazKhan47 Jun 19 '17 at 14:17

5 Answers5

12

That's how I do CORS in express applications, you have to remember about OPTIONS because for some frameworks there are 2 calls for CORS, first one is OPTIONS which checks what methods are available and then there is actual call, OPTIONS require just empty answer 200 OK

js

allowCrossDomain = function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
  if ('OPTIONS' === req.method) {
    res.send(200);
  } else {
    next();
  }
};

app.use(allowCrossDomain);
Community
  • 1
  • 1
maurycy
  • 8,455
  • 1
  • 27
  • 44
1

I have been struggled for a long time to achieve this, finally I got a solution for this now.

You can achieve same thing on server side instead of messing around client side. Here is the simple CORS Filter you need to add on server side.

package com.domain.corsFilter;

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    chain.doFilter(req, res);
}

public void init(FilterConfig filterConfig) {}

public void destroy() {}

}

Note: If you need help with imports for above, visit the below page topic: Filter requests for CORS Filter requests for CORS

Add this filter in your web.xml

filter
    filter-name corsFilter filter-name
    filter-class com.domain.corsFilter.SimpleCORSFilter filter-class
filter
filter-mapping
    filter-name corsFilter filter-name
    url-pattern /* url-pattern
filter-mapping

Add '<', '/>' tags in web.xml code, I had to remove to post this comment.

srinivas
  • 19
  • 3
0

Adding content-type header to following fixed the problem for me.

headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
Zoe
  • 27,060
  • 21
  • 118
  • 148
Dilhan Jayathilake
  • 1,860
  • 2
  • 17
  • 15
0

For those users who are finding an answer to make CORS requests from Angular JS. Firstly, don't spend enough time in adding unnecessary headers in your JS configuration. You don't have to change anything in your frontend. Just add the following annotation in your controller or at the method level.

@CrossOrigin

If you want to enable CORS for any specific URL then use the following annotation,

@CrossOrigin(origins = "http://localhost:9000")

The above solution is given for the Controller method CORS configuration. You shall also do Global CORS configuration by adding the following in your application class.

public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://localhost:9000");
            }
        };
    }

Reference : https://spring.io/guides/gs/rest-service-cors/

I hope this help. Peace! :)

georgeawg
  • 48,608
  • 13
  • 72
  • 95
imbond
  • 2,030
  • 1
  • 20
  • 22
-1

You just have to add some header properties in your server side response header.

Here is an example for NodeJS server

app.all("/api/*", function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
  res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
  return next();
});

It will solve AngularJS cross-domain AJAX call.

I have found this solution from How to enable CORS in AngularJs

Community
  • 1
  • 1