0

Goal: Save one JSON parameter in variable for use in JavaScript program.

Problem: The URL is valid (shows JSON in browser), but my AJAX call below fails: the success function is not working. (Access token from my test account.)

A hint would be highly appreciated.

Thanks

Felix

$.ajax({
    type: "GET",
    dataType: "jsonp",
    url: "https://api.moves-app.com/api/1.1/user/profile?access_token=7hACUBaguM0UI497MrDKJlvYPHu5813EErwFM6UJ7wURsI2d8iLj1BZ0R7Hru2gH",
    success: function(data) {
        alert("Test"); // Not working
    }
});
Felix
  • 13
  • 1
  • 3
  • What error do you get? I've seen problems happening in some environments (android, windows) and not in others (iOS) due to replacing special characters like space by the equivalent one. For example, spaces gets replaced by '%20'. Maybe you want to check something around that. – jbarrameda Jul 31 '15 at 18:05
  • The strange thing is that the call is working (try opening the URL in your browser: https://api.moves-app.com/api/1.1/user/profile?access_token=7hACUBaguM0UI497MrDKJlvYPHu5813EErwFM6UJ7wURsI2d8iLj1BZ0R7Hru2gH) -- but the AJAX call somehow breaks the program (code inside the success function is not executed)). Thanks – Felix Jul 31 '15 at 18:18
  • 3
    This api call cannot be made in the browser. It does not support CORS or JSONP, therefore it is not possible. – Kevin B Jul 31 '15 at 18:58

3 Answers3

1

You need a so called proxy page on the server where you load the page from. The page should be written in serverside language as PHP/Java (or other) where no cross domain restriction. you can call cURL for example. So you can call your proxy page, using ajax but with datatype:'json', not 'jsonp'. In you proxy page you have to do the call to https://api.moves-app.com and return the data as json string to jour script. Looks complex, but actually it isn't.

Reflective
  • 3,854
  • 1
  • 13
  • 25
  • indeed my answer gives him a simple proxy that I tested myself :) but you are totally rigth what you are saying – sandino Aug 01 '15 at 20:49
1

I will try to answer and help you. This is not working because browsers do not allow different domains async calls it is a mechanism that is used for security reasons and it is called same-domain-policy

You do not see the response because the browser is blocking it, if you use a REST plugin for firefox or chrome like POSTMAN you can see that actually there is a response, I indeed obtained a response from your link using postman:

{"userId":1368648652999913,"profile":{"firstDate":"20150202","currentTimeZone":{"id":"Europe/Berlin","offset":7200},"localization":{"language":"en","locale":"en_US","firstWeekDay":1,"metric":true},"caloriesAvailable":false,"platform":"ios"}}

You can make a proxy server (with php for example) to make the call for you and then use jquery to make the ajax to that proxy server, I made a simple proxy for you and it works, and the $.ajax call will work against it you can use it if you want:

<?php

 function executeRequest($url, $parameters = array(), $http_method = 'GET', array $http_headers = null, $form_content_type = 'multipart/form-data', $getResponseHeaders = false)
    {
        $certificate_file = null;
        $curl_options = array(
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_CUSTOMREQUEST  => $http_method
        );

        if ($getResponseHeaders){
            $curl_options[CURLOPT_HEADER] = true;
        }

        switch($http_method) {
            case 'POST':
                $curl_options[CURLOPT_POST] = true;
                /* No break */
            case 'PUT':
            case 'PATCH':

                /**
                 * Passing an array to CURLOPT_POSTFIELDS will encode the data as multipart/form-data,
                 * while passing a URL-encoded string will encode the data as application/x-www-form-urlencoded.
                 * http://php.net/manual/en/function.curl-setopt.php
                 */
                if(is_array($parameters) && 'application/x-www-form-urlencoded' === $form_content_type) {
                    $parameters = http_build_query($parameters, null, '&');
                }
                $curl_options[CURLOPT_POSTFIELDS] = $parameters;
                break;
            case 'HEAD':
                $curl_options[CURLOPT_NOBODY] = true;
                /* No break */
            case 'DELETE':
            case 'GET':
                if (is_array($parameters)) {
                    $url .= '?' . http_build_query($parameters, null, '&');
                } elseif ($parameters) {
                    $url .= '?' . $parameters;
                }
                break;
            default:
                break;
        }

        $curl_options[CURLOPT_URL] = $url;

        if (is_array($http_headers)) {
            $header = array();
            foreach($http_headers as $key => $parsed_urlvalue) {
                $header[] = "$key: $parsed_urlvalue";
            }
            $curl_options[CURLOPT_HTTPHEADER] = $header;
        }

        $ch = curl_init();
        curl_setopt_array($ch, $curl_options);
        // https handling
        if (!empty($certificate_file)) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
            curl_setopt($ch, CURLOPT_CAINFO, $certificate_file);
        } else {
            // bypass ssl verification
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        }
        if (!empty($curl_options)) {
            curl_setopt_array($ch, $curl_options);
        }
        $result = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        if ($curl_error = curl_error($ch)) {
            throw new Exception($curl_error, null);
        } else {
            $json_decode = json_decode($result, true);
        }
        curl_close($ch);

        return array(
            'result' => (null === $json_decode) ? $result : $json_decode,
            'code' => $http_code,
            'content_type' => $content_type
        );
    }


function getUserProfile($url){

    $parameters = array();

    $http_headers = array('Accept'=>'application/json',
                          'Content-Type'=>'application/x-www-form-urlencoded');
    $result = executeRequest($url, $parameters, 'GET', $http_headers, 0);
    return $result;
}

$url = $_GET['url'];

$result = getUserProfile($url);

echo $result['result'];

//Example usage:
//index.php?url=https://api.moves-app.com/api/1.1/user/profile?access_token=7hACUBaguM0UI497MrDKJlvYPHu5813EErwFM6UJ7wURsI2d8iLj1BZ0R7Hru2gH

?>
sandino
  • 3,813
  • 1
  • 19
  • 24
0

The problem is due to same-domain policy of the web security model. Your javascript can only call resources on the same domain of your web app. So, unless your web app is in https://api.moves-app.com, you cannot do ajax to it.

You need to look at how to perform cross-domain calls as suggested by Reflective. Look at these questions on what it is and how to do it.

  1. What is JSONP all about?
  2. AJAX cross domain call
  3. How to make cross domain request

One of the answers led to the creation of this wikipedia entry: JSONP.

Community
  • 1
  • 1
jbarrameda
  • 1,927
  • 2
  • 16
  • 19