简体   繁体   中英

JQuery Ajax Cross Domain Request and work with JSON String

I want to create a autocomplete function, where I need data as source from a different website. Therefore I want to create as first step a Ajax Request which just returns me the JSon String (I think it is Json), when I visit the link manually. I experienced some errors because of the "Allow Origin" thing.

This is the Link where I get all the data from:

http://www.futhead.com/15/players/search/quick/?term=

In the end (after term=) I want to add the input of my autocomplete field later and this link returns my different results for this.

This is what I've tried after googling a lot, which alerts "Error":

$.ajax({
     url:"http://www.futhead.com/15/players/search/quick/",
     data: "term=Ibarbo",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

What I want:

I want to display the results of this page in my php file sorted by the attributes.

This is the result of " http://www.futhead.com/15/players/search/quick/?term=ibarbo ":

[{"rating": 75, "club_image": "http://futhead.cursecdn.com/static/img/15/clubs/1842.png", "image": "http://futhead.cursecdn.com/static/img/15/players/204550.png", "revision_type": null, "workrates_short_string": "M/M", "xb_auction_average": null, "full_name": "V\u00edctor Ibarbo", "player_id": 204550, "id": 816, "nation_image": "http://futhead.cursecdn.com/static/img/15/nations/56.png", "pc_auction_average": null, "type": "15-player", "short_name": "V\u00edctor Ibarbo", "ps_auction_average": null, "club": 363, "nation": 12, "attr6": 78, "attr4": 80, "attr5": 39, "attr2": 71, "attr3": 66, "attr1": 91, "slug": "victor-ibarbo", "league": 1, "rare": true, "level": 0, "position": "ST"}]

Then I want to output:

Rating = 75

Club_image = http://futhead.cursecdn.com/static/img/15/players/204550.png

and so on.

With JSONP, jQuery creates a <script> tag and sends a function name to the remote host. The remote host needs to wrap their results in the function so that jQuery can later call the method to get the results.

See Here: jasonp cross domain request "wrapping json into a callback method"

If the remote host doesn't respond to jQuery's JSONP by wrapping the results, then it is likely that your best solution will be to call the service with a CURL request in PHP. You create a PHP page on your own site that returns the results, and then you no longer have a cross-site problem.

I've used the below code to make requests to other servers, in my case due to the need for credentials, which I stripped out, but it should also work to return the results on your own server. (Note, I may have created a bug in stripping out the credentials, etc., so not sure this works perfectly).

<?php
namespace WebServices {

    class CurlRequest {
        const REQUEST_TYPE_GET      = 'GET';
        const REQUEST_TYPE_POST     = 'POST';
        const REQUEST_TYPE_PUT      = 'PUT';
        const REQUEST_TYPE_DELETE   = 'DELETE';

        public function get($path, array $params=array() ) {
            return $this->httpRequest(self::REQUEST_TYPE_GET,$path,$params);
        }
        public function post($path, array $params=array() ) {
            return $this->httpRequest(self::REQUEST_TYPE_POST,$path,$params);
        }
        public function put($path, array $params=array() ) {
            return $this->httpRequest(self::REQUEST_TYPE_PUT,$path,$params);
        }
        public function remove($path, array $params=array() ) {
            return $this->httpRequest(self::REQUEST_TYPE_DELETE,$path,$params);
        }
        protected function httpRequest($type, $path, array $params=array()) {
            if( $type == self::REQUEST_TYPE_GET || $type == self::REQUEST_TYPE_DELETE) {
                $queryParams    = count($params)==0 ? '' : '&'.http_build_query($params);
                $path          .= $queryParams;
            }

            $curl               = curl_init($path);

            if( $type == self::REQUEST_TYPE_POST || $type == self::REQUEST_TYPE_PUT ) {
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params)); //-d
                curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); //-H
            }
            curl_setopt($curl, CURLOPT_VERBOSE, false); //-v
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $type);

            $response   = curl_exec($curl);
            $error      = curl_error($curl);
            $className  = get_class($this);
            curl_close($curl);

            if( $response === false || !empty($error) ) {
                $err    = empty($error)
                        ? "{$className}::httpRequest to '{$path}' failed"
                        : "{$className}::httpRequest to '{$path}' failed with message ({$error})\r\nRESPONSE: '{$response}'";
                error_log($err);
                throw new \Exception($err);
            }

            return json_decode($response);
        }
    }
}

On the page that you want to return the details, you would just need to do something like:

$curlRequest = new CurlRequest();
echo json_encode($curlRequest->get('http://www.futhead.com/15/players/search/quick/?term=ibarbo'));

you could also get rid of the json_decode in the method so it will just return the string and then you don't have to re-encode before outputting it for your service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM