Software engineering notes

JSON and JSONP

JSON 中文被編碼問題

如果 ajax 設定值沒有 dataType 的話, 就代表是以預設方式接收, 此時接收到 php 回傳的 json 格式時, 中文會被編碼, 長得像 :

\u518d\u807d\u9019\u9996\u6b4c\u7684\u9ede

有四種方式可以解決:

第一種 : 在 jQuery 的 $.ajax({ 的屬性裡 , 將 dataType 指定為 json

$.ajax({
    url: 'index.php/ajax_load/content_loading/',
    type: "POST",
    dataType: "json",
    (以下略..)

則 ajax 回傳的 json 格式就會自動被轉換成物件了, 所以就可以用一般我們使用陣列的方式來取值

例如使用foreach來alert出陣列裡的資料 :

for(qq in response)                (註 : response 為 php 回傳的 json 資料)
{
    alert(response[qq]);
}

第二種 : 與第一種原理一樣, 只不過我們手動把 json 轉為物件

response = JSON.parse(response);

這時 response 已被轉換為物件了, 就可以用陣列的方式來取值了

第三種 : 在 php 轉換 json 格式時動手腳, php 在轉換 json 時多加一個屬性 , 使它不將 unicode 轉碼

echo json_encode($json);

改成

echo json_encode($json, JSON_UNESCAPED_UNICODE);

中文就會正常地顯示了!

第四種 : 將 php 轉換json前的資料做urlencode , jQuery收到再urldecode

什麼是JSONP (JSON with Padding) :

目前以 ajax 傳輸資料首選的方法是用JSON格式 , 但是不同的網域就必須要以 JSONP 來跨域 , JSONP 不是一個新技術 , 是一種讓不同網域傳輸資料的方法 , 可以不必受限同源策略的限制 , 而達到不同網域以 ajax 傳輸資料的方法

未使用JSONP時, 會遇到的問題

假設我用localhost 以 ajax 請求一個線上網域的PHP檔, 來模擬不同網域 , 並且希望接收到回傳的JSON字串

localhost :

var car = new Array('toyota','BenZ','mazada');
var json = JSON.stringify(car);
$(document).ready(function(){
        $.ajax({
                url: 'http://test.com/test/jsonp_response.php',
                type: "json",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                data: json,
                success: function(response) {
                        alert(response);
                }
        });
});

遠端PHP檔(放在線上) :

$value = json_decode(file_get_contents('php://input'));
echo json_encode($value);

結果 : 什麼回應都沒有, 因為同源策略的限制, 所以沒辦法取得到json資料

使用 JSONP

localhost :

<script type='text/javascript'>
function ajax(){
        $.ajax({
                url: 'http://test.com/test/jsonp_response2.php',
                data: {name: 'test'},
                dataType: "jsonp",
                jsonp: 'callback',
                jsonpCallback: 'jsonpCallback',
                success: function() {
                        alert('success');
                }
        });
}
function jsonpCallback(data){
        alert(data.message);
}
</script>
<input type='button' value='click' onclick='ajax();'/>

遠端PHP檔(放在線上) :

<?php
    header("content-type: text/javascript");

    if(isset($_GET['name']) && isset($_GET['callback']))
    {
        $obj->name = $_GET['name'];
        $obj->message = "你好 " . $obj->name;

        echo $_GET['callback']. '(' . json_encode($obj) . ');';
    }
?>

結果 : OK!! 點擊 click按鈕 就會alert遠端回傳來的資料了!