Try ERPNext Buy Support Partners Foundation

No 'Access-Control-Allow-Origin' header error when using angular

i need to use frappe api call so to do that i have done as following

i have erpnext running at localhost:8003

i added following on nignx.conf file as in Access-Control-Allow-Origin Error for jquery $.ajax call

   location @webserver {
        if ($request_method = 'OPTIONS') {

                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-Mx- ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Contro$
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
        }
        if ($request_method = 'POST') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Contro$
        }

        if ($request_method = 'GET') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Contro$
        }
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Frappe-Site-Name thinksmart.site;
		proxy_set_header Host $host;
		proxy_set_header X-Use-X-Accel-Redirect True;
		proxy_read_timeout 120;
		proxy_redirect off;

		proxy_pass  http://frappe-bench-frappe;
	}

then i added below code in my html file

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script type="text/javascript">
	var app = angular.module('postserviceApp', []);
	app.controller('postserviceCtrl', function ($scope, $http) {
		// $scope.name = null;
		// $scope.age = null;
		// $scope.adress = null;
		$scope.lblMsg = null;
		$scope.usr = null;
		$scope.pwd = null;

		$scope.postdata = function (username,password) {
			$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";


			var data = {
				usr : 'Administrator',
				pwd : '123'
				// name: name,
				// age: age,
				// adress: adress
			};
			//Call the services
			$http.post('http://localhost:8003/api/method/login', JSON.stringify(data)).then(function (response) {
				if (response.data)
					$scope.msg = "Post Data Submitted Successfully!";
			}, function (response) {
				$scope.responseData = response.data;
				$scope.msg = "Service not Exists";
				$scope.statusval = response.status;
				$scope.statustext = response.statusText;
				$scope.headers = response.headers();
			});
		    // $http({
      //     		url: "//httpbin.org/post", 
      //     		method: "POST", 
      //     		data: data
      //   	  }).success(function(data, status) {
      //       	$scope.response = "POST Response: " + data.form.json;
      //       	$scope.fullResponse = JSON.stringify(data);
      //   	});
		};
	});
</script>

this js file is located at another folder of same pc so to make it run as localhost i use nodes.js
http-server ‘location of js folder’ -o

but i get this

 XMLHttpRequest cannot load http://localhost:8003/api/method/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:31338' is therefore not allowed access. The response had HTTP status code 417.

can any one help me this.

i tried a lot .

in case of development environment (bench start), nginx.conf is not used.

if both servers are localhost there should not be any cors issue.

Can you try simple code? like GET request to /api/method/version which is available for guest and check if it works?

@revant_one

okey

now i change my erpnext to a vps and now i added

  $http.get('http://***.**.**.**:****/api/method/version')
            // $http.post('http://thinksmart.bh/api/method/login', data1, config)
                .success(function (data, status, headers) {
                    $scope.PostDataResponse = data;
                    $scope.PostStatus = status;
                    $scope.PostStatusText = "statusText";

                    console.log(data.message);


                    // $http.get('http://**.**.**.**:****/api/method/frappe.auth.get_logged_user').
                    //     then(function(response) {
                    //         console.log(response.statusText);
                    //         console.log(response.data);
                    //         console.log(response);
                    //         $scope.greeting = response.data;
                    //     });
                })
                .error(function (data, status, header, config) {
                    $scope.ResponseDetails = "Data: " + data +
                        "<hr />status: " + status +
                        "<hr />headers: " + header +
                        "<hr />config: " + config;
                });
        };

in my js file

i get this
7.2.12

then i tried to do some post like below

 $http.post('http://**.**.**.**:****:9001/api/method/login', data1, config)
            // $http.post('http://thinksmart.bh/api/method/login', data1, config)
                .success(function (data, status, headers) {
                    $scope.PostDataResponse = data;
                    $scope.PostStatus = status;
                    $scope.PostStatusText = "statusText";

                    console.log(data.message);


                    // $http.get('http://**.**.**.**:****:9001/api/method/frappe.auth.get_logged_user').
                    //     then(function(response) {
                    //         console.log(response.statusText);
                    //         console.log(response.data);
                    //         console.log(response);
                    //         $scope.greeting = response.data;
                    //     });
                })
                .error(function (data, status, header, config) {
                    $scope.ResponseDetails = "Data: " + data +
                        "<hr />status: " + status +
                        "<hr />headers: " + header +
                        "<hr />config: " + config;
                });

then also get the expected result

{“home_page”:"/desk",“message”:“Logged In”,“full_name”:“Administrator”}
then i added new function

         $scope.GetData = function () {

           // use $.param jQuery function to serialize data from JSON 
            // var data = {
            // };
            // console.log(JSON.stringify(data));
            // alert(data);
        
            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }
            
            var headers = {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }

   

            $http.get('http://**.**.**.**:****/api/method/frappe.auth.get_logged_user')
            // $http.post('http://thinksmart.bh/api/method/login', data1, config)
                .success(function (data, status, headers) {
                    $scope.PostDataResponse = data;
                    $scope.PostStatus = status;
                    $scope.PostStatusText = "statusText";

                    console.log(data.message);


                    // $http.get('http://**.**.**.**:****/api/method/frappe.auth.get_logged_user').
                    //     then(function(response) {
                    //         console.log(response.statusText);
                    //         console.log(response.data);
                    //         console.log(response);
                    //         $scope.greeting = response.data;
                    //     });
                })
                .error(function (data, status, header, config) {
                    $scope.ResponseDetails = "Data: " + data +
                        "<hr />status: " + status +
                        "<hr />headers: " + header +
                        "<hr />config: " + config;
                });
        };

then i tried to call GetData i got this error

angular.js:10765 GET http://**.**.**.**:****:9001/api/method/frappe.auth.get_logged_user (anonymous function) @ angular.js:10765r @ angular.js:10558g @ angular.js:10268(anonymous function) @ angular.js:14792$eval @ angular.js:16052$digest @ angular.js:15870$apply @ angular.js:16160(anonymous function) @ angular.js:23618If @ angular.js:3346d @ angular.js:3334
same.html:1 XMLHttpRequest cannot load http://**.**.**.**:****:9001/api/method/frappe.auth.get_logged_user. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8080' is therefore not allowed access. The response had HTTP status code 403.

I solved this error by adding

add_header 'Access-Control-Allow-Origin' 'localhost:8003';
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content Type,Orgin;

in nginx.conf for all the post get options

thanks for your support

1 Like

This is happening because of the CORS (Cross Origin Resource Sharing) . For every HTTP request to a domain, the browser attaches any HTTP cookies associated with that domain. This is especially useful for authentication, and setting sessions. You are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request.

JSONP ( JSON with Padding ) is a method commonly used to bypass the cross-domain policies in web browsers. You’re on domain example.com , and you want to make a request to domain example.nett . To do so, you need to cross domain boundaries. JSONP is really a simple trick to overcome the XMLHttpRequest same domain policy. So, instead of using XMLHttpRequest we have to use < script > HTML tags, the ones you usually use to load JavaScript files , in order for JavaScript to get data from another domain.

Localhost

If you need to enable CORS on the server in case of localhost, you need to have the following on request header.

Access-Control-Allow-Origin: http://localhost:9999