Tag Archive get

Fetch API

Fetch API เป็นวิธีที่ใช้ทำ ajax แทน XMLHttpRequest (XHR) สามารถใช้ได้กับทุกบราวเซอร์ยกเว้น อ้ายอี (IE) แม้แต่ microsoft edge ก็ยังใช้ได้ แต่จริงๆ แล้วสามารถบังคับให้อ้ายอีใช้ได้โดยการเรียกใช้ github/fetch ช่วย

ไฟล์กลางที่ไว้ใช้ร่วมกัน

scripts.js

/*
pitt phunsanit
default fetch api options
version 1
*/
let fetchOptions = {
    "headers": {
        'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    "method": "post"
};

/*
pitt phunsanit
get status from fetch api
version 1
*/
function fetchStatus(Response) {
    if (Response.status >= 200 && Response.status < 300) {
        return Promise.resolve(Response);
    } else {
        return Promise.reject(new Error(Response.status + ' : ' + Response.statusText));
    }
}

ตัวอย่างการใช้ fetch แบบ GET

JavaScript/fetch.get.html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

      <meta name="author" content="Pitt Phunsanit">
      <title>fetch: get</title>
   </head>
   <body>
      <script src="../scripts.js"></script>
      <script>
fetch('http://localhost/snippets/PHP/json.json_encode.php?name=pitt&surname=phunsanit')
    .then(fetchStatus)
    .then(
        function(response) {

            response.json()
                .then(function(data) {
                    alert(JSON.stringify(data));
                });

        }
    )
    .catch(function(error) {
        alert(error);
    });
      </script>

</body></html>

เมื่อต้องการส่งข้อมูลแบบ POST ก็เพิ่ม option ไปเล็กน้อย
ตัวอย่างการ fetch แบบ POST

JavaScript/fetch.post.html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

      <meta name="author" content="Pitt Phunsanit">
      <title>fetch: post</title>
   </head>
   <body>
      <script src="../scripts.js"></script>
      <script>
fetchOptions.body = '[email protected]&name=pitt&surname=phunsanit';

fetch('http://localhost/snippets/PHP/json.json_encode.php', fetchOptions)
    .then(fetchStatus)
    .then(
        function(response) {

            response.json()
                .then(function(data) {
                    alert(JSON.stringify(data));
                });

        }
    )
    .catch(function(error) {
        alert(error);
    });
      </script>

</body></html>

อ่านเพิ่มเติม

curl: ส่งไฟล์

และแล้วก็มาถึงจุดที่รอคอย การส่งไฟล์ด้วย curl เหมือนที่ user upload ไฟล์เข้าเว็บ เหมาะกับการเอาไปเขียนโปรแกรมทรานสเฟอร์ไฟล์จากเว็บหนึ่งไปอีกที่หนึ่ง หรือจะเขียน bot ส่งไฟล์ออกไปเก็บเป็นข้อมูลสำรองก็ได้

[code language=”php” title=”curl_file.php”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>CURL: send file</title>
<link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
<div class="container">
<?php
if (count($_FILES) || count($_POST)) {
$url = ‘http://localhost/snippets/PHP/variables.php’;

if (count($_FILES)) {
$file_name_with_full_path = $_FILES[‘avatar’][‘tmp_name’];

if (function_exists(‘curl_file_create’)) {
/* php 5.5+ */
$_POST[‘avatar’] = curl_file_create($file_name_with_full_path);
} else {
$_POST[‘avatar’] = ‘@’ . realpath($file_name_with_full_path);
}
}

$ch = curl_init();

curl_setopt_array($ch, [
CURLOPT_ENCODING => ‘UTF-8’,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $_POST,
//CURLOPT_POSTFIELDS => http_build_query($_POST),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
]);

$result = curl_exec($ch);
curl_close($ch);

echo $result;
}
?>
<form action="curl_file.php" enctype="multipart/form-data" method="post">
<div class="form-group">
<label for="name">Name:</label>
<input class="form-control" id="name" name="name" type="text">
</div>
<div class="form-group">
<label for="avatar">Avatar:</label>
<input accept="image/gif, image/jpeg, image/x-png" class="form-control" id="avatar" name="avatar" type="file">
</div>
<div class="form-group">
<label for="address1">text address:</label>
<input class="form-control" id="address1" name="address[d]" type="text">
</div>
<div class="form-group">
<label for="address2">text address 2:</label>
<input class="form-control" id="address2" name="address[f]" type="text">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</body>

</html>[/code]

แต่เพราะ bug ของ function http_build_query ไม่สามารถ encoded query string ในกรณีที่มีไฟล์ได้อย่างถูกต้อง ทำให้ต้องส่งค่าฟอร์มไปโดยไม่เข้ารหัส ดังนั้น ค่าที่เป็น array จึงส่งค่าออกไปผิด[code language=”php” title=”function http_build_query bug”][address]Array
(
[name] => pitt phunsanit
[address] => Array
)[/code]

จากที่ค้นหาข้อมูลดู ยังไม่มีวิธีที่แก้ปัญหานี้ได้โดยไม่มีผลอาการข้างเคียง คงต้องรอให้ทางทีมงานพัฒนา PHP แก้ปัญหาให้ ตอนนี้ก็พยามหลีกเลี่ยงการส่งข้อมูลแบบเป็นอาร์เรไปก่อน อาจจะใช้ implode รวมข้อมูลก่อนส่งไปก็ได้

curl: ส่ง ฟอร์มแบบ post

หลังจากตัวอย่าง curl: ส่ง ฟอร์มแบบ get เรามาลองส่งข้อมูลแบบโพสต์กันต่อ เว็บไซต์ส่วนใหญ่จะนิยมส่งค่าในแบบฟอร์มแบบ post มากกว่าแบบ get เพราะว่า url จะดูสวยงาม ไม่เละเทะ ดูแล้วสบายตา และปลอดภัยกว่าการส่ข้อมูลให้เห็นง่ายๆ แบบใช้ url

[code language=”php” title=”curl_post.php”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>CURL: send post variables</title>
<link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
<div class="container">
<?php
if (count($_POST)) {
$url = ‘http://localhost/snippets/PHP/variables.php’;

$ch = curl_init();

curl_setopt_array($ch, [
CURLOPT_ENCODING => ‘UTF-8’,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => http_build_query($_POST),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
]);

$result = curl_exec($ch);
curl_close($ch);

echo $result;
}
?>
<form action="curl_post.php" enctype="multipart/form-data" method="post">
<div class="form-group">
<label for="name">Name:</label>
<input class="form-control" id="name" name="name" type="text">
</div>
<div class="form-group">
<label for="avatar">Avatar:</label>
<input accept="image/gif, image/jpeg, image/x-png" class="form-control" id="avatar" name="avatar" type="file">
</div>
<div class="form-group">
<label for="address1">text address:</label>
<input class="form-control" id="address1" name="address[]" type="text">
</div>
<div class="form-group">
<label for="address2">text address 2:</label>
<input class="form-control" id="address2" name="address[]" type="text">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</body>

</html>[/code]

จากการเปลี่ยน option ของ curl เล็กน้อยการส่งข้อมูลก็เปลี่ยนไปเป็นแบบ method post แล้ว แต่ก็ยังส่งไฟล์ไปไม่ได้อยู่ดีๆ ใจเย็นๆ ครับบทความหน้าส่งไฟล์ออกไปแน่ๆ ครับ

curl: ส่ง ฟอร์มแบบ get

curl หรือ Client URL Library เป็น function ที่ทำให้ php ทำตัวเป็น browser ที่ใช้เปิดเว็บรับส่งข้อมูลต่างๆ จาก server ของเราไปเซิฟเวอร์เครื่องอื่นๆ

ตัวอย่างการใช้งานที่ง่ายที่สุด คือการใช้ curl โดยการจำลองการส่งข้อมูลจากฟอร์มแบบเมธอดเก็ต หรือที่เรียกง่ายๆว่า ส่งข้อมูลแบบ url นั่นละ

[code language=”php” title=”curl_get.php”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>CURL: send get variables</title>
<link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
<div class="container">
<?php
if (count($_GET)) {
$queryString = http_build_query($_GET);
$url = ‘http://localhost/snippets/PHP/variables.php?’ . $queryString;

echo ‘<br>$url = ‘, $url;

$ch = curl_init();

curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
]);

$result = curl_exec($ch);
curl_close($ch);

echo $result;
}
?>
<form action="curl_get.php" method="get">
<div class="form-group">
<label for="name">Name:</label>
<input class="form-control" id="name" name="name" type="text">
</div>
<div class="form-group">
<label for="avatar">Avatar:</label>
<input accept="image/gif, image/jpeg, image/x-png" class="form-control" id="avatar" name="avatar" type="file">
</div>
<div class="form-group">
<label for="address1">text address:</label>
<input class="form-control" id="address1" name="address[]" type="text">
</div>
<div class="form-group">
<label for="address2">text address 2:</label>
<input class="form-control" id="address2" name="address[]" type="text">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</body>

</html>[/code]ในการแปลงข้อมูลจากแบบฟอร์มจะใช้ [code language=”php” title=”Generate URL-encoded query string”]$queryString = http_build_query($_GET);[/code] แปลงให้อยู่ในรูปแบบคิวรี่สตริงที่ส่งไปกับ url ได้

การทดสอบทำได้โดยไฟล์ variables.php จำลองเป็นฝั่งรับข้อมูล[code language=”php” title=”variables.php”]<?php
echo ‘<h3>$_COOKIE</h3><pre>’, print_r($_COOKIE, true), ‘</pre>’;
echo ‘<h3>$_FILES</h3><pre>’, print_r($_FILES, true), ‘</pre>’;
echo ‘<h3>$_GET</h3><pre>’, print_r($_GET, true), ‘</pre>’;
echo ‘<h3>$_POST</h3><pre>’, print_r($_POST, true), ‘</pre>’;
echo ‘<h3>$_REQUEST</h3><pre>’, print_r($_REQUEST, true), ‘</pre>’;
[/code]

ข้อมูลที่ส่งไปจะแสดงกลับมาให้เราเห็น แต่สังเกตุได้ว่า ถึงจะส่งไฟล์ avatar ฝั่งรับก็จะไม่ได้รับ เพราะการส่งข้อมูลแบบนี้จะมีข้อเสียคือ ไม่สามารถส่งไฟล์ได้

jQuery: upload แบบ ajax

ตัวอย่างการใช้ jQuery upload ไฟล์แบบ ajax[code language=”html” title=”ajax.form.upload.html”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>jQuery: form > send file</title>
<link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<style>
.progressbar {
background: #c00000;
clear: both;
height: 10px;
width: 0;
}

.progressLoaded {
width: 50px;
}

.progressLoaded::after {
content: " bytes";
}

.progressPercent {
width: 50px;
}

.progressPercent::after {
content: " %";
}

.progressTotal {
float: left;
width: 50px;
}

.progressTotal::after {
content: " bytes";
}

.progressTotal::before {
content: " of ";
}
</style>
</head>

<body>
<h1>upload file with ajax</h1>
<form action="values.php" class="form-horizontal" enctype="multipart/form-data" id="formA" method="post">
<div class="form-group">
<label class="col-sm-2 control-label" for="socialidI">หมายเลขบัตรประชาชน</label>
<div class="col-sm-10">
<input class="form-control" id="socialidI" maxlength="13" name="socialid" placeholder="หมายเลขบัตรประชาชน" type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="photoI">ภาพถ่าย</label>
<div class="col-sm-10">
<input class="form-control" id="photoI" name="photo" placeholder="upload file" type="file">
</div>
</div>
<div class="form-group">
<div class="col-sm-10 text-right">
<button type="submit" class="btn btn-success">ส่งข้อมูล</button>
</div>
</div>
</form>
<div class="col-sm-12">
<h4>Progress</h4>
<div class="progressLoaded"></div>
<div class="progressTotal"></div>
<div class="progressPercent"></div>
<div class="progressbar"></div>
</div>
<div class="col-sm-12" id="resultA"></div>
<script src="../vendor/components/jquery/jquery.min.js"></script>
<script>
function xhrProgress(xhr) {
if (xhr.upload) {
// For handling the progress of the upload
xhr.upload.addEventListener(‘progress’, function (e) {
if (e.lengthComputable) {
$(‘.progressTotal’).html(e.total);
$(‘.progressLoaded’).html(e.loaded);

percentComplete = parseInt((e.loaded / e.total * 100), 10);
$(‘.progressPercent’).html(percentComplete);
$(‘.progressbar’).css("width", percentComplete + ‘%’);
}
}, false);
}
return xhr;
}

$(function () {

var formA = $(‘#formA’);

formA.submit(function (event) {
event.preventDefault();

$.ajax({
"beforeSend": function (jqXHR, settings) {
/* แยกตัวแปรไว้ตรวจสอบข้อมูล */
var params = settings.data;

if (settings.data.get(‘socialid’) == ”) {

jqXHR.abort();
alert(‘กรุณากรอกหมายเลขบัตรประชาชน’);

return false;
}

if (settings.data.get(‘photo’).name == ”) {

jqXHR.abort();
alert(‘กรุณาอัพโหลดรูปภาพ’);

return false;
}

},
"contentType": false,
"data": new FormData(formA[0]),
"method": "POST",
"processData": false,
"success": function (data, textStatus, jqXHR) {
$(‘#resultA’).html(data);
},
"url": "values.php",
"xhr": function () {
return xhrProgress($.ajaxSettings.xhr());
},

});

});

});
</script>
</body>

</html>[/code]ไฟล์ที่รอรับข้อมูล[code language=”php” title=”values.php”]<?php
echo ‘FILE<pre>’, print_r($_FILES, true), ‘</pre>’;
echo ‘GET<pre>’, print_r($_GET, true), ‘</pre>’;
echo ‘POST<pre>’, print_r($_POST, true), ‘</pre>’;
[/code]

วิธีนี้ใช้ความสามารถใหม่ FormData ที่ใช้กับ browser เก่าแก่กว่า Internet Explorer 10 หรือ Edge ไม่ได้ ดูเพิ่มเติม

jQuery: ส่ง form แบบ ajax

พื้นฐานการส่งข้อมูลจากแบบฟอร์มไปประมวลผลโดย jQuery Ajax ทำได้ง่ายๆ

องค์ประกอบ

  1. ส่วนประกอบแรกก็คือฟอร์มที่ใช้กรอกข้อมูล[code language=”html” title=”ajax.form.html”]<form action="values.php" id="formA" method="post">

    <input name="socialid" type="text">

    <button type="submit" class="btn btn-success">ส่งข้อมูล</button>
    …</form>[/code]ส่วนสำคัญคือ id (id=”formA”) ของฟอร์มที่จะใช้อ้างถึงใน JavaScript
  2. ส่วน JavaScript ที่จะรวบรวมข้อมูลส่งออกไปหาเซิร์ฟเวอร์[code language=”javascript” title=”send form by ajax”]$(function() {
    var formA = $(‘#formA’);

    formA.submit(function(event) {
    event.preventDefault();

    $.ajax({
    "data": formA.serialize(),
    "method": "POST",
    "success": function(data, textStatus, jqXHR) {
    $(‘#resultA’).html(data);
    },
    "url": "values.php",
    });
    });
    });[/code]

    data
    ข้อมูลที่จะส่งออกไป ตัวอย่างนี้ข้อมูลในแบบฟอร์มจะถูกรวบรวมโดย function .serialize()

    method
    คือจะส่งข้อมูลไปหา server แบบ get หรือ post
    success
    code ในส่วนนี้จะทำงานเมื่อทำงานสำเร็จเท่านั้น
    url
    เป็น url ที่จะส่งข้อมุลไปหา
  3. ฝั่ง server ที่ทำหน้าที่ประมวลผล[code language=”php” title=”values.php”]<?php
    echo ‘GET<pre>’, print_r($_GET, true), ‘</pre>’;
    echo ‘POST<pre>’, print_r($_POST, true), ‘</pre>’;[/code]
  4. ส่วนแสดงผล เพราะว่าการส่งแบบ ajax จะส่งไปเป็นแบบ background จึงควรมีการแสดงให้เห็นว่ามีการทำงานเกิดขึ้น ใน code ชุดนี้คือแสดงผลในพื้นที่[code language=”html” tilte=”พื้นที่แสดงผล”]<div class="col-sm-12" id="resultA"></div>[/code]

ตัวอย่าง code ที่เขียนเสร็จแล้ว[code language=”html” title=”ajax.form.html”]<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>jQuery: Form Send</title>
<link href="../vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>

<body>
<h1>พร้อมเพย์ (PromptPay)</h1>
<form action="values.php" class="form-horizontal" id="formA" method="post">
<div class="form-group">
<label class="col-sm-2 control-label">โอนเงินด้วย</label>
<div class="col-sm-10">
<div class="radio">
<label>
<input checked name="way" type="radio" value="socialid"> หมายเลขบัตรประชาชน
</label>
</div>
<div class="radio">
<label>
<input name="way" type="radio" value="phone"> หมายเลขโทรศัพท์
</label>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="socialidI">หมายเลขบัตรประชาชน</label>
<div class="col-sm-10">
<input class="form-control" id="socialidI" maxlength="13" name="socialid" placeholder="หมายเลขบัตรประชาชน" type="number">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="phoneI">หมายเลขโทรศัพท์</label>
<div class="col-sm-10">
<input class="form-control" id="phoneI" maxlength="11" name="phone" placeholder="หมายเลขโทรศัพท์" type="tel">
</div>
</div>
<div class="form-group">
<label for="amount" class="col-sm-2 control-label">จำนวนเงิน</label>
<div class="col-sm-10">
<div class="input-group">
<input class="form-control" id="amount" max="5000" min="0" name="amount" placeholder="จำนวนเงิน" type="number">
<div class="input-group-addon">&#3647;</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-10 text-right">
<button type="submit" class="btn btn-success">โอนเงิน</button>
</div>
</div>
</form>
<div class="col-sm-12" id="resultA"></div>
<script src="../vendor/components/jquery/jquery.min.js"></script>
<script>
$(function () {
var formA = $(‘#formA’);

formA.submit(function (event) {
event.preventDefault();

$.ajax({
"data": formA.serialize(),
"method": "POST",
"success": function (data, textStatus, jqXHR) {
$(‘#resultA’).html(data);
},
"url": "values.php",
});
});
});
</script>
</body>

</html>[/code]และ code ที่ประมวลผลข้อมูล[code language=”php” title=”values.php”]<?php
echo ‘GET<pre>’, print_r($_GET, true), ‘</pre>’;
echo ‘POST<pre>’, print_r($_POST, true), ‘</pre>’;[/code]