Solved

AngularJS: How to call API on a remote server

Posted on 2015-02-19
7
358 Views
Last Modified: 2015-02-20
Hi, I am separating an AngularJS App with Slim PHP API onto 2 servers.
The full app is here: dev02.photomonkey.ch (A)
The new frontend is here: dev03.photomonkey.ch (B)

(donwload link for entire app: http://www.angularcode.com/download-link/?url=https://app.box.com/s/pqr0wo3osvoahyh7qtsa)

It turns out the backend is working, ie when I call http://dev02.photomonkey.ch/api/v1/products directly from the browser I get the JASON Data.
However when the app on dev03.photomonkey.ch wants to get data, it issues the following GET: http://dev03.photomonkey.ch/api/v1/products
How can I get the data factory to call a different endpoint?
$http gets injected by angular, can it be changed in the data.js?
How is this generally done when a frontend needs to call a backend on a remote server?
Thank you!


NOTE: Changing var serviceBase = 'api/v1/'; to anything else will still get a 404, as that path just gets appended to the endpoint which is http://dev03.photomonkey.ch, but needs to be http://dev02.photomonkey.ch

*************************************
.htaccess
*************************************

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]


*************************************
data.js
*************************************

app.factory("Data", ['$http', '$location',
    function ($http, $q, $location) {

        var serviceBase = 'api/v1/';

        var obj = {};

        obj.get = function (q) {
            return $http.get(serviceBase + q).then(function (results) {
                return results.data;
            });
        };
        obj.post = function (q, object) {
            return $http.post(serviceBase + q, object).then(function (results) {
                return results.data;
            });
        };
        obj.put = function (q, object) {
            return $http.put(serviceBase + q, object).then(function (results) {
                return results.data;
            });
        };
        obj.delete = function (q) {
            return $http.delete(serviceBase + q).then(function (results) {
                return results.data;
            });
        };
        return obj;
}]);




*************************************
Entire APP on dev02.photomonkey.ch
Use this only as the backend! (A)
*************************************

webroot of dev02.photomonkey.ch
|   index.html
|  
+---api
|   +---libs
|   |   \---Slim
|   |       |   Environment.php
|   |       |   etc
|   |       |  
|   |       +---Exception  
|   |       +---Helper    
|   |       +---Http
|   |       \---Middleware
|   \---v1
|           .htaccess
|           config.php
|           dbHelper.php
|           index.php
|          
+---app
|       app.js
|       data.js
|       directives.js
|       productsCtrl.js
|      
+---css      
+---fonts    
+---js    
\---partials

*************************************
New frontend dev03.photomonkey.ch (B)
*************************************
webroot of dev03.photomonkey.ch
|   index.html
+---app
|       app.js
|       data.js
|       directives.js
|       productsCtrl.js
|      
+---css      
+---fonts    
+---js  
\---partials
0
Comment
Question by:jacobs99
  • 4
  • 3
7 Comments
 
LVL 11

Expert Comment

by:Radek Baranowski
ID: 40620020
Hello again

as I told you, this is probably CORS problem, that means that your service on dev02 is not Cross-domain enabled.

The link with description has been posted in the other question.

If you launch you page in Chrome (from dev03) but press F12 before to track network traffic for this session you will see that trying to get data from dev02 ends with XMLHTTPRequest failing due to Cross-origin limitation. That's why I'm saying this is CORS problem.
0
 

Author Comment

by:jacobs99
ID: 40620057
Hi Radek,
I am sorry. With all due respect, please consider that you may be on the wrong track.

Clicking the GET in the Chrome-F12-network and clicking the header tab shows that in fact it is trying to reach http://dev03.photomonkey.ch/api/v1/products which does not have the API exactly as explained in the question.

I am looking for an answer to the question: How to get the $http angular object to point to the correct endpoint.

I have no expertise whatsoever in Angular.

Thank you
0
 
LVL 11

Expert Comment

by:Radek Baranowski
ID: 40620115
Yes and hence 404 error.

If you set serviceBase to http://dev02...  on dev03 in data.js you will see XMLHTTPRequest error in Chrome F12 network debug.

Url param for $http object is set as serviceBase + q where q is 'products' and together they form Url which yields you 404 error instead of timeout/invalid response

But yeah i can be on the wrong track of course.
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:jacobs99
ID: 40620631
I set the following in the htaccess file on dev02 and am now able to execute a GET from dev03 to dev02:

# Cross domain access
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

However, POST, PUT and DELETE do not work (yet!)
0
 
LVL 11

Accepted Solution

by:
Radek Baranowski earned 500 total points
ID: 40620690
I can see now this:

"XMLHttpRequest cannot load http://dev02.photomonkey.ch/api/v1/products. The 'Access-Control-Allow-Origin' header contains multiple values 'http://dev03.photomonkey.ch, *', but only one is allowed. Origin 'http://dev03.photomonkey.ch' is therefore not allowed access."

So you would probably need to leave only '*' out there.
0
 

Author Comment

by:jacobs99
ID: 40620694
I added the following to the index.php. Removed the header add from htaccess.
Tested GET, PUT, POST and DELETE. All working so far.

if (isset($_SERVER['HTTP_ORIGIN'])) {
        header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Max-Age: 86400');    // cache for 1 day
}

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && (  
       $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST' ||
       $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'DELETE' ||
       $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'PUT' )) {
             header('Access-Control-Allow-Origin: *');
             header("Access-Control-Allow-Credentials: true");
             header('Access-Control-Allow-Headers: X-Requested-With');
             header('Access-Control-Allow-Headers: Content-Type');
             header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
             header('Access-Control-Max-Age: 86400');
      }
  exit;
}
0
 

Author Comment

by:jacobs99
ID: 40620698
Radek, my bad.
For sure you are right that the problem was that dev02 was not cross domain enabled as you originally posted!
Thank you for your help!
Peter
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've been asked to discuss some of the UX activities that I'm using with my team. Here I will share some details about how we approach UX projects.
These days socially coordinated efforts have turned into a critical requirement for enterprises.
This video teaches users how to migrate an existing Wordpress website to a new domain.
The viewer will learn how to count occurrences of each item in an array.

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now