เคยไหมกับปัญหาการใช้ Api ข้าม Domain แล้วจะพบว่าไม่สามารถใช้งานได้ เนื่องจาก browser ตรวจสอบแล้วพบว่า ส่วนร้องขอข้อมูลกับส่วนประมวลผลข้อมูลเป็นคนละ domain กัน ดูจากรูปด้านล่าง http://location:81/test/json.html ไปยัง Api ที่อยู่ บน http://localhost:8080/testApi.php จะไม่สามารถแสดงผลได้ เนื่องจากการ Cross domain นั่นเอง
แล้วจะทำอย่างไรถึงจะใช้งานได้ล่ะ ? JSONP เป็นอีกหนึ่งทางเลือก ของการแก้ปัญหานี้ วิธีการนั้นทำได้โดย
- โดนรูปแบบของการส่งข้อมูล แทนที่จะเป็น json ธรรมดาก็เปลี่ยนเป็น json พร้อมกับ callback function สามารถทำได้โดยการเพิ่ม option dataType เป็น JSONP และ jsonpCallback ตามด้วยฟังก์ชั่น ที่เราเตรียมไว้ กับ ข้อมูล
- ส่ง callback query เพื่อให้ api บน server ทราบชื่อ callback function ที่เราเตรียมไว้ โดยรูปแบบของ json กับ jsonp จะแตกต่างกัน ตามรูปที่แสดง
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}}; } ?>