[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

AngularJS: How to call API on a remote server

Posted on 2015-02-19
7
Medium Priority
?
406 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

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

Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

Question has a verified solution.

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

This article was originally published on Monitis Blog, you can check it here . Today it’s fairly well known that high-performing websites and applications bring in more visitors, higher SEO, and ultimately more sales. By the same token, downtime…
When the s#!t hits the fan, you don’t have time to look up who’s on call, draft emails, call collaborators, or send text messages. An instant chat window is definitely the way to go, especially one like HipChat. HipChat is a true business app. An…
This video teaches users how to migrate an existing Wordpress website to a new domain.
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses

656 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