?
Solved

AngularJS: How to call API on a remote server

Posted on 2015-02-19
7
Medium Priority
?
409 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 12

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 12

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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

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 12

Accepted Solution

by:
Radek Baranowski earned 2000 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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article discusses how to implement server side field validation and display customized error messages to the client.
In this blog, we’ll look at how improvements to Percona XtraDB Cluster improved IST performance.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).
Suggested Courses
Course of the Month16 days, 17 hours left to enroll

862 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