category: Ajax

JavaScript - Dynamic Load script || JSONP Callback

on 2015-06-08

JavaScript - Dynamic Load script || JSONP Callback

Intro

Sometimes we need dynamic load script or handle jsonp callback

And we need handle script onload or jsonp callback onload or something error

How to do?

Use onload, onerror method

Code

if (typeof UTIL == 'undefined' || !UTIL) {
    var UTIL = {};
}
UTIL.createEl = {
    get: function(sTag, oAttr, handleOnLoad, handleError) {
        var el = document.createElement(sTag);
        for (var i in oAttr) {
            el[i] = oAttr[i];
        }
        if (handleOnLoad) {
            el.onload = handleOnLoad;
        }
        if (handleError) {
            el.onerror = handleError;
        }
        this.append(el);
        return el;
    },
    append: function(dNode) {
        var dHead = document.getElementsByTagName('head')[0] || document.body;
        dHead.appendChild(dNode);
    },
    remove: function(dNode) {
        setTimeout(function() {
            dNode.parentNode.removeChild(dNode);
            dNode = null;
        }, 0);
    },
    js: function(sUrl, handleOnLoad, handleError) {
        var dNode = this.get('script', {
            src: sUrl,
            type: 'text/javascript'
        }, handleOnLoad, handleError);
        return dNode;
    },
    css: function(sUrl, sMedia) {
        if (!sMedia) {
            sMedia = 'all';
        }
        return this.get('link', {
            'href':sUrl,
            'rel':'stylesheet',
            'type':'text/css',
            'media':sMedia
        });
    }
};

Example

var run = function() {
    alert('OK');
},
errorHandle = function() {
    alert('Error');
};
UTIL.createEl.js('http://tysh310246.blogspot.com/feeds/posts/default?alt=json&callback=myFunction', run, errorHandle);

function myFunction (data) {
    console.log(data);
}

Refer - JavaScript Madness: Dynamic Script Loading Refer - Script Loading issue « 小莊記事

Read more

AJAX - REST

on 2015-01-12

AJAX - REST

REST 當道的現在, 不得不了解一下如何實作 CRUD(create, read, update, delete) 本文 server side 以 php 為例子

var xhr = new XMLHttpRequest();

xhr.open('GET', 'example.html', true);
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        document.getElementById('myDiv').innerHTML = xhr.responseText;
    }
};
xhr.send();

上面為一個簡單的 AJAX 行為

在此之前須了解在做 AJAX 行為時, 資料是如何跟 request 一起帶到 server side 大致上有 3 種

  • FormData
  • application/x-www-form-urlencoded
  • payload

前面 2 種是用傳統的 form 包起來一起帶到 server side 再經由 php 解析 GET / POST 由於 php 只有 $_GET & $POST 這無法達到真正的 rest(不過有人硬幹出來 tronice/epv) 所以必須由其他方式實作 最簡單的實作就是使用 $_SERVER['REQUEST_METHOD'] 來捕捉 4 種 request 的 method

$method = $_SERVER['REQUEST_METHOD'];
print_r($method);
switch($method)
{
    case "PUT":
        // do somethong
    break;
    case "GET":
        // do somethong
    break;
    case "DELETE":
        // do somethong
    break;
    case "POST":
        // do somethong
    break;
}

這是最簡單實作 rest 的方式 目前 php framework 大部份都有實作 rest, 所以也不用擔心加重開發上的負擔

FormData or application/x-www-form-urlencoded or payload?

接下來介紹一下這 3 種方式在前後端的行為差異 相信大家都了解 form 表單 submit 那在 AJAX 崛起之後把 Content-Type 設定成 application/x-www-form-urlencoded 是一個普遍的做法 jQuery 也是採用這方式實作的

setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’)

var obj = {
        'user': 'ted',
        'password': '123456'
    },
    jsonData;
jsonData = JSON.stringify(obj);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        document.getElementById('myDiv').innerHTML = xhr.responseText;
    }
};
xhr.send('json=' + jsonData);

FormData

之後出現 FormData 這個物件, 它的優勢在於使用比 application/x-www-form-urlencoded 的方式簡單而且 Content-Typemultipart/form-databoundary 的方式傳送 這有一個好處就是可以實作 AJAX 的 file upload, 而不是傳統的 form 表單檔案上傳 至於 AJAX 上傳的好處就是可以捕捉上傳進度、取消上傳, 做多檔上傳的排程(目前常見的 cloud storage service 幾乎都是這樣做)

var formData = new FormData();
formData.append('str', 'string');
formData.append('num', 123);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php');
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        document.getElementById('myDiv').innerHTML = xhr.responseText;
    }
};
xhr.send(formData);

以上兩種方式在 PHP 中皆是以 $_GET or $_POST 接下來處理

if (isset($_POST['json']))
{
    echo $_POST['json'];
}
if (isset($_POST['str']))
{
    echo $_POST['str'];
}
if (isset($_POST['num']))
{
    echo $_POST['num'];
}

payload

這方法是個高端的方法, 第一次遇到這方法是在 AngularJS 上, 不過貌似國外開始漸漸這樣做了 這有方式個好處, 就是接收端不須經由 $_POST or $_GET 進來, 直接用 file_get_contents("php://input") 接收 client 端的 data 還有效能上的優勢, 因為不經由 $_POST or $_GET 進來可以減少成本增進效能 在 AngularJS 中會把 Content-Type 指定為 application/json 方便 server side 識別與處理

var obj = {
        'user': 'ted',
        'password': '123456'
    },
    jsonData;
jsonData = JSON.stringify(obj);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php', true);
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        document.getElementById('myDiv').innerHTML = xhr.responseText;
    }
};
xhr.send('json=' + jsonData);

在 PHP 必須用 file_get_contents("php://input") 來接資料

$request = file_get_contents("php://input");
var_dump($request);
$data = json_decode($request);
echo '<br>';
echo 'data:';
echo '<br>';
echo 'User:' . $data->user;
echo '<br>';
echo 'Pwd:' . $data->password;

Finally

關於使用 FormData 與 payload 處理 file upload 之後會有文章補充

Read more