Solved

AngularJS: How to call API on a remote server

Posted on 2015-02-19
7
349 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:jacobs99
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This article discusses four methods for overlaying images in a container on a web page
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will get a basic understanding of what section 508 compliance can entail, learn about skip navigation links, alt text, transcripts, and font size controls.

763 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

7 Experts available now in Live!

Get 1:1 Help Now