Cross Domain with JSONP e

เคยไหมกับปัญหาการใช้ Api ข้าม Domain แล้วจะพบว่าไม่สามารถใช้งานได้ เนื่องจาก browser ตรวจสอบแล้วพบว่า ส่วนร้องขอข้อมูลกับส่วนประมวลผลข้อมูลเป็นคนละ domain กัน ดูจากรูปด้านล่าง http://location:81/test/json.html ไปยัง Api ที่อยู่ บน http://localhost:8080/testApi.php จะไม่สามารถแสดงผลได้ เนื่องจากการ Cross domain นั่นเอง

แล้วจะทำอย่างไรถึงจะใช้งานได้ล่ะ ? JSONP เป็นอีกหนึ่งทางเลือก ของการแก้ปัญหานี้ วิธีการนั้นทำได้โดย

  1. โดนรูปแบบของการส่งข้อมูล แทนที่จะเป็น json ธรรมดาก็เปลี่ยนเป็น json พร้อมกับ callback function สามารถทำได้โดยการเพิ่ม option dataType เป็น JSONP และ jsonpCallback ตามด้วยฟังก์ชั่น ที่เราเตรียมไว้ กับ ข้อมูล
  2. ส่ง callback query เพื่อให้ api บน server ทราบชื่อ callback function ที่เราเตรียมไว้ โดยรูปแบบของ json กับ jsonp จะแตกต่างกัน ตามรูปที่แสดง

Code ตัวอย่างด้านล่างนี้นะครับ

json.html :

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>JQuery (cross-domain) JSONP Twitter example</title>
        <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
        <script>
            $(document).ready(function(){
              
        $('document').ready(function() {
            
          function photos (data) { 
            console.log(data);
          };
      
          var pm_url = 'http://localhost:8080/testApi.php?callback=photos'; 
          $.ajax({
            url: pm_url,
            //type: 'GET',
            success: function(json) {
              $("#data").text(JSON.stringify(json));
              console.dir(JSON.stringify(json));
            },
            error: function(e) {
              $("#data").text(e.message);
               console.log(e.message);
            },
            dataType: 'JSONP',
            jsonpCallback: 'photos',
            //jsonp: 'callback', 
          });
        });
            });
       
      //angular
      var app = angular.module('MyApp', []);
      app.controller('MyCtrl', function($scope, $http) {
        $scope.firstName = "John";
        $scope.lastName = "Doe";
        $scope.colorwheelies = "wait";
        
        $http.jsonp('http://localhost:8080/testApi.php?callback=angular.callbacks._0')
         .success(function(data){
          console.log(data);
          $scope.colorwheelies = data;
          //console.log(data);
          });
          
        $scope.search = function() {
           
        };
      }); 
        </script>
    </head>
    <body  ng-app="MyApp">
        
      Ajax Result :	<span id="data"></span><br/>
     
      <div ng-controller="MyCtrl">
       <p>
        Angularjs result : {{colorwheelies}}
       </p>
      </div> 
    </body>
</html>

testApi.php:

<?php
  
  $callback_fn = isset($_GET['callback'])?$_GET['callback']: 'angular.callbacks._0';
   
  $arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
  $result['result'] = $arr;
  
  if(false){
    echo  $callback_fn. "(".json_encode($result).")" ; //for angularjs as default;
    //angular.callbacks._0 ({"result":{"a":1,"b":2,"c":3,"d":4,"e":5}});
  }else{
    echo  json_encode($result) ;
    //{"result":{"a":1,"b":2,"c":3,"d":4,"e":5}};
  }
?>