การใช้ไลบรารีของไคลเอ็นต์ JavaScript (v2.0)

คําเตือน: หน้านี้เกี่ยวกับ API แบบเก่าของ Google ซึ่งก็คือ Google Data API โดยเกี่ยวข้องกับ API ที่แสดงอยู่ในไดเรกทอรี Google Data API เท่านั้น โดยหลาย API ถูกแทนที่ด้วย API ที่ใหม่กว่า สําหรับข้อมูลเกี่ยวกับ API ใหม่โดยเฉพาะ โปรดดูเอกสารประกอบของ API ใหม่ ดูข้อมูลเกี่ยวกับการให้สิทธิ์คําขอด้วย API ใหม่ได้ที่การตรวจสอบสิทธิ์และการให้สิทธิ์บัญชี Google

เอกสารนี้อธิบายวิธีใช้ไลบรารีของไคลเอ็นต์ JavaScript เพื่อส่งคําขอของ Google Data API และตีความการตอบกลับที่แสดงผล

Google มีชุดไลบรารีของไคลเอ็นต์ในภาษาโปรแกรมต่างๆ สําหรับการโต้ตอบกับบริการที่มี API ข้อมูล เมื่อใช้ไลบรารีเหล่านี้ คุณจะสร้างคําขอ API, ส่งไปยังบริการ และรับคําตอบได้

เอกสารนี้ให้ข้อมูลทั่วไปเกี่ยวกับการใช้ไลบรารีของไคลเอ็นต์ JavaScript พร้อมตัวอย่างการใช้งานทั่วไป

ผู้ชม

เอกสารนี้มีไว้สําหรับโปรแกรมเมอร์ JavaScript ที่ต้องการเขียนแอปพลิเคชันไคลเอ็นต์ซึ่งสามารถโต้ตอบกับบริการข้อมูลของ Google

เอกสารนี้จะถือว่าคุณเข้าใจแนวคิดทั่วไปเบื้องหลังโปรโตคอล Google Data API และจะถือว่าคุณรู้วิธีเขียนโปรแกรมใน JavaScript ด้วย

สําหรับข้อมูลอ้างอิงเกี่ยวกับคลาสและวิธีการที่ไลบรารีของไคลเอ็นต์มีให้ โปรดดูเอกสารอ้างอิงไลบรารีของไคลเอ็นต์ JavaScript (ในรูปแบบ JSdoc)

เอกสารนี้ออกแบบมาให้อ่านตามลําดับ โดยตัวอย่างแต่ละรายการจะสร้างขึ้นจากตัวอย่างก่อนหน้านี้

ข้อกำหนดในการใช้งาน

คุณตกลงที่จะปฏิบัติตามข้อกําหนดในการใช้งานไลบรารีของไคลเอ็นต์ JavaScript ของ Google เมื่อใช้ไลบรารีของไคลเอ็นต์ JavaScript

ภาพรวมรูปแบบข้อมูลและขั้นตอนการควบคุม

ไลบรารีของไคลเอ็นต์ JavaScript จะใช้ชุดคลาสเพื่อแสดงองค์ประกอบที่ Google Data API ใช้

หมายเหตุ: การแสดงข้อมูลที่เกี่ยวข้องคือ JSON แต่ไลบรารีของไคลเอ็นต์จะมีเลเยอร์ Abstraction ดังนั้นคุณไม่ต้องทํางานกับข้อมูล JSON โดยตรง หากต้องการทํางานกับ JSON โดยตรงโดยไม่มีไลบรารีของไคลเอ็นต์ โปรดดูการใช้ JSON กับ Google Data API

ไลบรารีมีวิธีการที่ช่วยให้คุณส่งข้อมูลไปยังและรับข้อมูลจากบริการที่มี API ข้อมูลได้แบบไม่พร้อมกัน เช่น เมธอด google.gdata.calendar.CalendarService.getEventsFeed() จะส่งคําขอฟีดไปยัง Google ปฏิทิน พารามิเตอร์หนึ่งที่คุณส่งคือฟังก์ชันการต่อเนื่อง หรือเรียกอีกอย่างว่าการเรียกกลับ บริการจะแสดงฟีดในรูปแบบ JSON โดยการเรียกใช้ฟังก์ชันต่อเนื่อง จากนั้นไคลเอ็นต์จะเรียกใช้เมธอด get ต่างๆ เพื่อใช้ข้อมูลในรูปแบบออบเจ็กต์ JavaScript ได้

หากต้องการเพิ่มรายการใหม่ ให้สร้างรายการโดยใช้คลาสและเมธอดของไลบรารีของไคลเอ็นต์ จากนั้นจึงเรียกใช้เมธอด feed.insertEntry() เพื่อส่งรายการใหม่ไปยังบริการ และคุณใส่ฟังก์ชันการทํางานต่อเนื่องอีกครั้ง ซึ่งบริการจะเรียกใช้เมื่อเพิ่มรายการเรียบร้อยแล้ว

หากคุณเพิ่งเริ่มใช้ JavaScript กระบวนการควบคุมอาจสับสนเล็กน้อย หลังจากเรียกเมธอด เช่น getEventsFeed() หรือ insertEntry() ในกรณีส่วนใหญ่แล้ว สคริปต์จะสิ้นสุดลง การดําเนินการจะกลับมาทํางานอีกครั้งในฟังก์ชันต่อเนื่องเมื่อบริการส่งข้อมูลที่ขอ ดังนั้น การดําเนินการที่ไคลเอ็นต์ทํากับข้อมูลที่แสดงผลควรจะทําในฟังก์ชันต่อเนื่อง หรือเรียกจากฟังก์ชันนั้น คุณอาจต้องทําให้ตัวแปรบางตัวเป็นตัวแปรสากลจึงจะใช้งานได้ในหลายๆ ฟังก์ชัน

สําหรับข้อมูลเพิ่มเติมเกี่ยวกับการจัดโปรแกรมรูปแบบนี้ โปรดดู "รูปแบบการส่งต่อเนื่อง" ใน Wikipedia

เกี่ยวกับสภาพแวดล้อมที่รองรับ

ปัจจุบันเรารองรับเฉพาะแอปพลิเคชันไคลเอ็นต์ JavaScript ที่ทํางานในหน้าเว็บในเบราว์เซอร์เท่านั้น เบราว์เซอร์ที่รองรับในปัจจุบัน ได้แก่

  • Firefox 2.x และ 3.x
  • Internet Explorer 6, 7 และ 8
  • Safari 3.x และ 4.x
  • Google Chrome (ทุกเวอร์ชัน)

ไลบรารีของไคลเอ็นต์ JavaScript จะจัดการการสื่อสารทั้งหมดกับเซิร์ฟเวอร์ของบริการ หากคุณเป็นนักพัฒนาซอฟต์แวร์ JS ที่มีประสบการณ์ คุณอาจคิดว่า "แต่นโยบายต้นทางเดียวกันล่ะ" ไลบรารีของไคลเอ็นต์ JavaScript จะช่วยให้ไคลเอ็นต์ส่งคําขอ Google Data จากโดเมนใดก็ได้ ขณะเดียวกันก็ยังคงเป็นไปตามรูปแบบความปลอดภัยของเบราว์เซอร์

โปรดดูภาพรวมการตรวจสอบสิทธิ์ด้วย Google Data API ที่ภาพรวมการตรวจสอบสิทธิ์ Google Data API ส่วนที่เหลือของเอกสารนี้จะถือว่าคุณคุ้นเคยกับข้อมูลพื้นฐานเกี่ยวกับวิธีการทํางานของระบบนี้

ตัวอย่างแอปพลิเคชันไคลเอ็นต์

หากต้องการดูไลบรารีของไคลเอ็นต์ JavaScript จริง โปรดไปที่หน้าตัวอย่าง

บทแนะนําและตัวอย่าง

ตัวอย่างต่อไปนี้แสดงวิธีส่งคําขอ API ข้อมูลหลายรายการโดยใช้ไลบรารีของไคลเอ็นต์ JavaScript

เพื่อให้ข้อมูลมีความเฉพาะเจาะจงมากขึ้น ตัวอย่างเหล่านี้แสดงวิธีโต้ตอบกับบริการหนึ่งๆ โดยเฉพาะ: Google ปฏิทิน เราจะกําหนดตําแหน่งที่ปฏิทินแตกต่างจากบริการอื่นๆ ของ Google เพื่อช่วยคุณปรับตัวอย่างเหล่านี้สําหรับใช้กับบริการอื่นๆ โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับปฏิทินที่เอกสาร API ของ Google ปฏิทิน

กําลังโหลดไลบรารี

ลูกค้าต้องขอรหัสไลบรารีของไคลเอ็นต์จากเซิร์ฟเวอร์ก่อนจึงจะใช้ไลบรารีของไคลเอ็นต์ได้

เริ่มต้นโดยใช้แท็ก <script> ในส่วน <head> ของเอกสาร HTML เพื่อโหลดตัวโหลด Google AJAX API:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

คุณลดการรับส่งไปยังเซิร์ฟเวอร์ของ Google และลดเวลาในการตอบสนองได้โดยโหลดคลังล่วงหน้า หากต้องการโหลดแพ็กเกจบางรายการจากตัวโหลด Google AJAX API โดยตรง (โดยไม่ใช้ google.load() โปรดดูด้านล่าง) ให้ใช้ข้อมูลต่อไปนี้

<script type="text/javascript"
      src="https://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3Agdata%2Cversion%3A2.x%2Cpackages%3A%5Bblogger%2Ccontacts%5D%7D%5D%7D"></script>

หมายเหตุ: URL ของ src ควรเข้ารหัส URL อย่างสมบูรณ์ ตัวอย่างเช่น
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script>

หากคุณไม่ได้โหลดโมดูลอัตโนมัติ คุณสามารถโหลดไลบรารีของไคลเอ็นต์ Google Data ได้โดยใช้ตัวอย่างถัดไปในโค้ดการตั้งค่า JavaScript หลังจากโหลดตัวโหลดทั่วไป การเรียกนี้ต้องมาจากส่วน<head>ของเอกสาร HTML (หรือจากไฟล์ JavaScript ที่รวมอยู่ในแท็ก <script> ในส่วน <head> ของเอกสาร HTML)

google.load("gdata", "2");

หรือคุณจะขอบริการบางอย่างแทนทั้งไลบรารีก็ได้ ตัวอย่างนี้ดาวน์โหลดเฉพาะแพ็กเกจสําหรับ Blogger และ Contacts:

google.load("gdata", "2.x", {packages: ["blogger", "contacts"]});

พารามิเตอร์ที่ 2 ที่ส่งไปยัง google.load() คือหมายเลขเวอร์ชันที่ขอของไลบรารีไคลเอ็นต์ JavaScriptรูปแบบการกําหนดหมายเลขรุ่นของเราจําลองมาจากรูปแบบที่ Google Maps API ใช้ หมายเลขเวอร์ชันที่เป็นไปได้และความหมาย

"1"
การแก้ไขครั้งที่ 2 ของเวอร์ชันหลัก 1
"1.x"
การแก้ไขรุ่นล่าสุดของเวอร์ชัน 1
"1.s"
การแก้ไขล่าสุดที่มีความเสถียรของเวอร์ชันหลัก 1 ในบางครั้ง เราจะประกาศไลบรารีของไคลเอ็นต์บางเวอร์ชันว่า "เสถียร" ตามความคิดเห็นที่ได้รับจากนักพัฒนาซอฟต์แวร์ อย่างไรก็ตาม เวอร์ชันดังกล่าวอาจไม่มีฟีเจอร์ล่าสุด
"1.0", "1.1" ฯลฯ
เวอร์ชันของไลบรารีที่เฉพาะเจาะจง พร้อมหมายเลขการแก้ไขหลักและหมายเลขรองที่ระบุไว้

หลังจากเรียกใช้ google.load() คุณต้องบอกให้ตัวโหลดรอจนกระทั่งหน้าโหลดเสร็จ จากนั้นจึงเรียกใช้โค้ด

google.setOnLoadCallback(getMyFeed);

โดยที่ getMyFeed() เป็นฟังก์ชันที่กําหนดไว้ในส่วนถัดไปของเอกสารนี้ ใช้แนวทางนี้แทนที่จะต่อเชื่อมเครื่องจัดการ onload กับเอลิเมนต์ <body>

การขอฟีดที่ไม่ผ่านการตรวจสอบสิทธิ์

หากต้องการขอฟีดที่ไม่ได้ตรวจสอบสิทธิ์ ให้เพิ่มโค้ดต่อไปนี้ลงในไฟล์ JavaScript หรือในแท็ก <script> ในไฟล์ HTML

ในโค้ดต่อไปนี้ getMyFeed() จะเรียกใช้ก่อน (โดยตัวโหลด AJAX API ตามที่อธิบายไว้ในส่วนก่อนหน้า)

โดยระบบจะเรียก setupMyService() เพื่อสร้างการเชื่อมต่อ (แทนออบเจ็กต์ CalendarService) ไปยัง Google ปฏิทิน เราได้ดึงโค้ดการสร้างบริการมาไว้ในฟังก์ชันแยกต่างหากสําหรับรูปแบบแล้ว ภายหลัง เราจะแก้ไขฟังก์ชัน setupMyService() โดยขึ้นอยู่กับตัวเลือกการตรวจสอบสิทธิ์ของคุณ

หลังจากตั้งค่าบริการแล้ว getMyFeed() จะเรียกเมธอด getEventsFeed() ของไลบรารีของไคลเอ็นต์เพื่อขอฟีด

เราระบุ URL ของฟีดในตัวแปรร่วมเพื่อให้ใช้งานได้ในฟังก์ชันต่อๆ ไป ในตัวอย่างนี้ เราใช้ URL ฟีดสาธารณะ (ไม่ได้ตรวจสอบสิทธิ์) สําหรับผู้ใช้ชื่อ liz@gmail.com หรือคุณจะใช้ default แทนอีเมลของผู้ใช้แทนผู้ใช้ที่ตรวจสอบสิทธิ์ก็ได้

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/public/full";

function setupMyService() {
  var myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
  return myService;
}

function getMyFeed() {
  myService = setupMyService();

  myService.getEventsFeed(feedUrl, handleMyFeed, handleError);
}

โปรดทราบว่าเรากําลังทําให้ myService เป็นตัวแปรร่วม เพื่อช่วยให้ใช้ฟังก์ชันได้ง่ายขึ้นในภายหลัง

หากต้องการให้โค้ดข้างต้นทํางานในไคลเอ็นต์ของคุณเอง คุณต้องใช้อีเมลของผู้ใช้จริงสําหรับบัญชีปฏิทินที่มีปฏิทินที่แชร์แบบสาธารณะ

หมายเหตุ: เมื่อสร้างออบเจ็กต์ CalendarService แบบใหม่ ไลบรารีของไคลเอ็นต์จะเรียกใช้เมธอดชื่อ google.gdata.client.init() ซึ่งจะตรวจสอบว่าเบราว์เซอร์ที่ไคลเอ็นต์ทํางานอยู่หรือไม่ หากมีข้อผิดพลาด ไลบรารีของไคลเอ็นต์จะแสดงข้อความแสดงข้อผิดพลาดแก่ผู้ใช้ หากต้องการจัดการข้อผิดพลาดประเภทนี้ด้วยตนเอง คุณสามารถเรียกใช้ google.gdata.client.init(handleInitError) อย่างชัดเจนก่อนสร้างบริการ โดย handleInitError() เป็นฟังก์ชันของคุณ หากเกิดข้อผิดพลาด init ฟังก์ชันของคุณจะรับออบเจ็กต์ข้อผิดพลาดแบบมาตรฐาน ซึ่งคุณสามารถทําสิ่งที่ต้องการได้

ในการเรียก getEventsFeed() อาร์กิวเมนต์ที่ 2 คือ handleMyFeed ซึ่งเป็นฟังก์ชันเรียกกลับ โปรดดูด้านล่าง Google ปฏิทินจะดําเนินการกับคําขอ จากนั้นหากคําขอประสบความสําเร็จ ก็จะส่งออบเจ็กต์ "รากฟีด" ที่มีฟีดที่ขอไปยังโค้ดเรียกกลับ รากฟีดคือออบเจ็กต์คอนเทนเนอร์ที่มีฟีด

อาร์กิวเมนต์ที่ 3 กับ getEventsFeed() เป็นฟังก์ชันการจัดการข้อผิดพลาดที่ไม่บังคับ ถ้าไลบรารีของไคลเอ็นต์พบข้อผิดพลาด จะเรียกใช้เครื่องจัดการข้อผิดพลาดที่ระบุแทนฟังก์ชันเรียกกลับที่สําเร็จ ออบเจ็กต์ที่ไลบรารีของไคลเอ็นต์ส่งผ่านเป็นอาร์กิวเมนต์ไปยังเครื่องจัดการข้อผิดพลาดคืออินสแตนซ์ของออบเจ็กต์ JavaScript Error ที่มีพร็อพเพอร์ตี้ cause เพิ่มเติม

ต่อไปนี้คือฟังก์ชันกลับและเครื่องจัดการข้อผิดพลาดเวอร์ชันแบบง่าย

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
}

function handleError(e) {
  alert("There was an error!");
  alert(e.cause ? e.cause.statusText : e.message);
}

เรากําลังจัดการข้อผิดพลาดโดยการแสดงต่อผู้ใช้เท่านั้น เครื่องจัดการข้อผิดพลาดของไคลเอ็นต์น่าจะซับซ้อนมากขึ้น ในบางบริบทจะไม่มีการระบุสาเหตุ ดังนั้นในกรณีดังกล่าว ตัวแฮนเดิลข้อผิดพลาดของเราจึงกลับไปแสดงพร็อพเพอร์ตี้ message มาตรฐาน

โปรดทราบว่าเนื่องจากโค้ดนี้ไม่ได้ตรวจสอบสิทธิ์ จึงใช้ได้โดยการรับฟีดสาธารณะเท่านั้น

กำลังตรวจสอบสิทธิ์

ไลบรารีของไคลเอ็นต์ JavaScript ใช้งานได้ 2 โหมด หากคุณเขียนแกดเจ็ต จะใช้ฟีเจอร์ที่เรียกว่าพร็อกซี OAuth สําหรับการตรวจสอบสิทธิ์ หากมีการเข้าถึงได้จากแอปพลิเคชัน JavaScript แบบสแตนด์อโลน จะใช้ระบบการตรวจสอบสิทธิ์ AuthSub สําหรับข้อมูลเกี่ยวกับการตรวจสอบสิทธิ์ โปรดดูเอกสารภาพรวมการตรวจสอบสิทธิ์ของ Google Data API เนื้อหาที่เหลือของส่วนนี้จะถือว่าคุณคุ้นเคยกับข้อมูลพื้นฐานเกี่ยวกับวิธีการทํางานของระบบนี้

ก่อนใช้การตรวจสอบสิทธิ์กับโค้ดตัวอย่างที่ระบุไว้ในเอกสารนี้ ให้เปลี่ยน URL ของฟีดจากสาธารณะเป็นส่วนตัว

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/private/full";

การตรวจสอบสิทธิ์ในไคลเอ็นต์ของเว็บด้วย AuthSub

ระบบการให้สิทธิ์ "AuthSub สําหรับ JavaScript" ของ Google ไม่สามารถใช้งานได้อีกต่อไป

แต่เราขอแนะนําให้ใช้ OAuth 2.0 สําหรับแอปพลิเคชันฝั่งไคลเอ็นต์

การตรวจสอบสิทธิ์ในแกดเจ็ตด้วยพร็อกซี OAuth

ต่อไปนี้เป็นภาพรวมคร่าวๆ เกี่ยวกับสิ่งที่จะเกิดขึ้นระหว่างขั้นตอนการตรวจสอบสิทธิ์สําหรับแกดเจ็ต

  1. แกดเจ็ตของคุณโหลดเป็นครั้งแรกและพยายามเข้าถึงข้อมูลของผู้ใช้โดยใช้ Google Data API
  2. คําขอล้มเหลวเพราะผู้ใช้ยังไม่ได้ให้สิทธิ์เข้าถึงข้อมูล ออบเจ็กต์การตอบกลับมี URL (ใน response.oauthApprovalUrl) สําหรับหน้าการอนุมัติ OAuth แกดเจ็ตของคุณควรมีวิธีเปิดหน้าต่างใหม่โดยใช้ URL นั้น
  3. ในหน้าการอนุมัติ ผู้ใช้จะเลือกให้สิทธิ์/ปฏิเสธการเข้าถึงแกดเจ็ตของคุณ หากสําเร็จ ระบบจะนําผู้ใช้ไปยังหน้า oauth_callback ที่คุณระบุ โปรดใช้ http://oauth.gmodules.com/gadgets/oauthcallback เพื่อประสบการณ์ของผู้ใช้ที่ดีที่สุด
  4. ถัดไป ผู้ใช้ปิดหน้าต่างป๊อปอัป เราได้ระบุเครื่องจัดการป๊อปอัปที่คุณสามารถใช้ตรวจจับการปิดหน้าต่างการอนุมัติไว้เพื่อช่วยแจ้งแกดเจ็ตของคุณว่าผู้ใช้ได้อนุมัติการอนุมัติแล้ว หรือแกดเจ็ตอาจแสดงลิงก์ (เช่น "ฉันอนุมัติการเข้าถึง") เพื่อให้ผู้ใช้สามารถคลิกด้วยตนเองหลังจากปิดหน้าต่างนี้
  5. แกดเจ็ตของคุณพยายามเข้าถึง Google Data API เป็นครั้งที่ 2 ด้วยการขอข้อมูลของผู้ใช้อีกครั้ง การดําเนินการนี้สําเร็จ
  6. แกดเจ็ตของคุณได้รับการตรวจสอบสิทธิ์และเริ่มทํางานตามปกติแล้ว

ในแกดเจ็ต ให้เพิ่มองค์ประกอบ <OAuth> ในส่วน <ModulePrefs> ดังนี้

<ModulePrefs>
...
<OAuth>
  <Service name="google">
    <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> 
    <Request url="https://www.google.com/accounts/OAuthGetRequestToken?
                  scope=http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/" method="GET" /> 
    <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?
                        oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> 
  </Service>
</OAuth>
...
</ModulePrefs>

ในส่วนนี้ ให้เปลี่ยนพารามิเตอร์การค้นหาต่อไปนี้

  • scope

    พารามิเตอร์ที่จําเป็นใน URL คําขอ แกดเจ็ตของคุณจะเข้าถึงข้อมูลได้จาก scope ที่ใช้ในพารามิเตอร์นี้เท่านั้น ในตัวอย่างนี้ แกดเจ็ตจะเข้าถึงข้อมูล Blogger และปฏิทิน แกดเจ็ตสามารถขอข้อมูลสําหรับขอบเขตเดียวหรือหลายขอบเขตได้ (ดังตัวอย่างต่อไปนี้)

  • oauth_callback

    พารามิเตอร์ที่ไม่บังคับใน URL การให้สิทธิ์ หน้าการอนุมัติ OAuth จะเปลี่ยนเส้นทางไปยัง URL นี้หลังจากที่ผู้ใช้อนุมัติการเข้าถึงข้อมูลของตน คุณเลือกที่จะปล่อยพารามิเตอร์นี้ ตั้งค่าเป็น "หน้าที่ได้รับอนุมัติ" ของคุณเอง หรือจะเลือกใช้ http://oauth.gmodules.com/gadgets/oauthcallback ก็ได้ หลังจากนั้นจะมอบประสบการณ์การใช้งานที่ดีที่สุดเมื่อผู้ใช้ติดตั้งแกดเจ็ตของคุณเป็นครั้งแรก หน้าเว็บนั้นมีข้อมูลโค้ด JavaScript ที่ปิดหน้าต่างป๊อปอัปโดยอัตโนมัติ

ต่อไป ให้โหลดไลบรารีของไคลเอ็นต์ JavaScript ในส่วน <Content> ของแกดเจ็ต แก้ไขฟังก์ชัน setupMyService() จากตัวอย่างก่อนหน้า เพื่อเรียกเมธอด useOAuth() ของออบเจ็กต์บริการ การดําเนินการนี้จะบอกให้แกดเจ็ตใช้พร็อกซี OAuth เพื่อตรวจสอบสิทธิ์แทน AuthSub เทมเพลตด้านล่างนี้ให้คุณได้เริ่มต้นใช้งาน

<Content type="html">
<![CDATA[
  ...
  <script src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
    var myService = null;
    
    function setupMyService() {
      myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
      myService.useOAuth('google');
      fetchData();
    }
    
    function initGadget() {
      google.load('gdata', '2.x');
      google.setOnLoadCallback(setupMyService);
    }

    function fetchData() {            
      var callback = function(response) {
        if (response.oauthApprovalUrl) {
        
          // TODO: Display "Sign in" link (response.oauthApprovalUrl contains the URL) 
          
        } else if (response.feed) {
        
          // TODO: show results
          
        } else {
        
          // TODO: handle the error
          
        }
      };

      myService.getEventsFeed('http://www.google.com/calendar/feeds/default/public/full', callback, callback);
    }
    
    gadgets.util.registerOnLoadHandler(initGadget);
  </script>
  ...
]]> 
</Content>

โปรดทราบว่าการเรียกใช้ google.accounts.user.login(scope) ถูกนําออกแล้ว พร็อกซีจะจัดการการตรวจสอบสิทธิ์ให้คุณ

หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับการเขียนแกดเจ็ต Google Data API ซึ่งรวมถึงรายละเอียดของสิ่งที่ fetchData() ควรมี อ่านบทความเกี่ยวกับการสร้างแกดเจ็ต Google Data หรืออ่านเอกสารฉบับเต็มในการเขียนแกดเจ็ต OAuth

การแทรกรายการใหม่

หากต้องการสร้างกิจกรรมในปฏิทินใหม่ ให้ดําเนินการต่อจากตัวอย่างก่อนหน้านี้โดยแก้ไขจุดสิ้นสุดของฟังก์ชัน handleMyFeed() เพื่อเรียกใช้ฟังก์ชันใหม่ ดังนี้

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
  insertIntoMyFeed(myResultsFeedRoot);
}

ในฟังก์ชันใหม่ ให้ใช้เครื่องมือสร้าง CalendarEventEntry เพื่อสร้างรายการใหม่ก่อน จากนั้นแทรกรายการโดยระบุการเรียกกลับสําหรับบริการเพื่อเรียกใช้เมื่อแทรกเสร็จ

function insertIntoMyFeed(feedRoot) {
  var newEntry = new google.gdata.calendar.CalendarEventEntry({
      authors: [{
        name: "Elizabeth Bennet",
        email: "liz@gmail.com"
      }],
      title: {
        type: 'text', 
        text: 'Tennis with Darcy'
      },
      content: {
        type: 'text', 
        text: 'Meet for a quick lesson'
      },
      locations: [{
        rel: "g.event",
        label: "Event location",
        valueString: "Netherfield Park tennis court"
      }],
      times: [{
        startTime: google.gdata.DateTime.fromIso8601("2007-09-23T18:00:00.000Z"),
        endTime: google.gdata.DateTime.fromIso8601("2007-09-23T19:00:00.000Z")
      }]
  });
  feedRoot.feed.insertEntry(newEntry, handleMyInsertedEntry, handleError);
}

โปรดทราบว่าชื่อของพร็อพเพอร์ตี้ออบเจ็กต์แต่ละรายการที่ใช้ในเครื่องมือสร้างตรงกับชื่อของเมธอด setter ที่ใช้สําหรับพร็อพเพอร์ตี้นั้น (เช่น ตรงกับชื่อช่อง JSON ที่เกี่ยวข้อง)

โปรดทราบว่าคุณไม่สามารถระบุสตริงวันที่และเวลา ISO 8601 สําหรับ startTime และ endTime เท่านั้น คุณต้องเรียกใช้สตริงดังกล่าวผ่านเมธอด fromIso8601() ก่อน

บริการส่งคืนสําเนาของรายการที่แทรกเป็นออบเจ็กต์ entryRoot และส่งผ่านออบเจ็กต์นั้นไปยังโค้ดเรียกกลับ

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
}

การขอรายการที่เจาะจง

หากต้องการขอรายการที่เจาะจง ก่อนอื่นให้แก้ไขฟังก์ชัน handleMyInsertedEntry() เพื่อเรียกฟังก์ชันคําขอรายการใหม่

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
  requestMySpecificEntry(insertedEntryRoot.entry.getSelfLink().getHref());
}

โค้ดต่อไปนี้ช่วยให้คุณขอรายการที่เจาะจงที่คุณแทรกไว้ในตัวอย่างก่อนหน้านี้ได้

ในบริบทของตัวอย่างชุดนี้ การดึงข้อมูลนั้นไม่จําเป็นมาก เนื่องจากปฏิทินส่งคืนรายการที่แทรกอยู่แล้ว แต่สามารถใช้เทคนิคเดียวกันเมื่อคุณรู้ URI ของรายการนั้น

function requestMySpecificEntry(entryURI) {
  myService.getEventsEntry(entryURI, handleMySpecificEntry, handleError);
}

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
}

ตัวอย่างนี้เหมือนกับตัวอย่าง getEventsFeed() ยกเว้นเราจะเรียกเมธอด getEventEntry() ของบริการเพื่อให้รายการที่เฉพาะเจาะจง และ URI จะแตกต่างออกไปเล็กน้อย โดยจะใช้ "ค่าเริ่มต้น" เพื่ออ้างอิงถึงปฏิทินหลักสําหรับผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์ และจะมีรหัสรายการต่อท้าย

นอกจากนี้ เราต้องใช้รายการที่ได้รับมาได้ในภายหลัง ดังนั้นเราจะคัดลอกข้อมูลดังกล่าวไปยังตัวแปรร่วม

รายการที่ค้นหา

หากต้องการค้นหาข้อความแบบเต็ม ก่อนอื่นให้แก้ไขฟังก์ชัน handleMySpecificEntry() เพื่อเรียกใช้ฟังก์ชันการค้นหาใหม่

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
  searchMyFeed();
}

จากนั้น หากต้องการดึงรายการที่ตรงกันรายการแรกจากการค้นหา ให้ใช้โค้ดต่อไปนี้

function searchMyFeed() {
  var myQuery = new google.gdata.calendar.CalendarEventQuery(feedUrl);
  myQuery.setFullTextQuery("Tennis");
  myQuery.setMaxResults(10);
  myService.getEventsFeed(myQuery, handleMyQueryResults, handleError);
}

function handleMyQueryResults(myResultsFeedRoot) {
  if (myResultsFeedRoot.feed.getEntries()[0]) {
    alert("The first search-match entry's title is: " + myResultsFeedRoot.feed.getEntries()[0].getTitle().getText());
  }
  else {
    alert("There are no entries that match the search query.");
  }
}

กําลังอัปเดตรายการ

หากต้องการอัปเดตรายการที่มีอยู่ ให้เพิ่มบรรทัดไปยังส่วนท้าย handleMyQueryResults() เพื่อเรียกใช้ฟังก์ชันการอัปเดตใหม่โดยทําดังนี้

  updateMyEntry();

จากนั้นใช้โค้ดต่อไปนี้ ในตัวอย่างนี้ เราจะเปลี่ยนชื่อรายการที่ได้รับก่อนหน้านี้ (ซึ่งมีอยู่ในออบเจ็กต์ส่วนกลางชื่อ myEntryRoot ในตัวอย่างก่อนหน้านี้) จากข้อความเก่า ("เทนนิสที่มีดาร์ซี") เป็น "การประชุมสําคัญ"

function updateMyEntry() {
  myEntryRoot.entry.getTitle().setText("Important meeting");
  myEntryRoot.entry.updateEntry(handleMyUpdatedEntry, handleError);
}

function handleMyUpdatedEntry(updatedEntryRoot) {
  alert("Entry updated. The new title is: " + updatedEntryRoot.entry.getTitle().getText());
}

และเช่นเดียวกับเมธอดปฏิทินทั้งหมด เมธอด updateEntry() จะกําหนด URI การแก้ไขที่ถูกต้องเพื่อใช้ในการอัปเดตรายการโดยอัตโนมัติ คุณจึงไม่ต้องระบุ URI ดังกล่าวอย่างชัดแจ้ง

กําลังลบรายการ

หากต้องการลบรายการที่อัปเดตแล้ว ให้เพิ่มบรรทัดใน handleMyUpdatedEntry() ก่อน ดังนี้

 deleteMyEntry(updatedEntryRoot);

จากนั้นใช้โค้ดต่อไปนี้

function deleteMyEntry(updatedEntryRoot) {
  updatedEntryRoot.entry.deleteEntry(handleMyDeletedEntry, handleError);
}

function handleMyDeletedEntry() {
  alert("Entry deleted");
}

เมธอด deleteEntry() จะระบุ URI การแก้ไขที่ถูกต้องเพื่อใช้ในการลบรายการโดยอัตโนมัติ

โปรดทราบว่าไม่มีการส่งคืนรายการใดๆ หากมีการเรียกกลับ เราจะรู้ว่าการลบนั้นสําเร็จ หากการลบไม่สําเร็จ deleteEntry() จะโทรหา handleError() แทนการโทรไปยัง handleMyDeletedEntry()

การใช้ ETag

หมายเหตุ: ETag ใช้ได้เฉพาะกับบริการที่ใช้โปรโตคอลข้อมูลของ Google เวอร์ชัน 2.0

บทนำ

ไคลเอ็นต์ JavaScript ของ Google Data เวอร์ชัน 2 เพิ่มการรองรับ ETag ETag คือตัวระบุที่ระบุเวอร์ชันของรายการหนึ่งๆ โดยเฉพาะ กรณีนี้มี 2 กรณี ดังนี้

  • ทํา "การเรียกข้อมูลแบบมีเงื่อนไข" ซึ่งไคลเอ็นต์ขอและเซิร์ฟเวอร์ส่งรายการเฉพาะในกรณีที่รายการมีการเปลี่ยนแปลงตั้งแต่ครั้งล่าสุดที่ไคลเอ็นต์ขอเท่านั้น
  • การตรวจสอบว่าลูกค้าหลายรายไม่ได้เขียนทับการเปลี่ยนแปลงของกันและกันโดยไม่ตั้งใจ ซึ่งทําได้โดยการอัปเดตและลบไม่สําเร็จหากไคลเอ็นต์ระบุ ETag เก่าสําหรับรายการ

ETag มีอยู่ 2 ประเภท ได้แก่ อ่อนและแข็งแรง ETag อ่อนคือเริ่มต้นด้วย W/ เสมอ เช่น W/"D08FQn8-eil7ImA9WxZbFEw" เราไม่รับประกันว่า ETag ที่ไม่รัดกุมจะมีการเปลี่ยนแปลงเมื่อรายการเปลี่ยนแปลง ดังนั้น HTTP จึงอนุญาตให้นําไปใช้สําหรับการเรียกข้อมูลแบบมีเงื่อนไขเท่านั้น ETag ที่รัดกุมจะระบุรายการเวอร์ชันใดเวอร์ชันหนึ่งโดยเฉพาะ และสามารถใช้สําหรับทั้งการเรียกข้อมูลแบบมีเงื่อนไขและในระหว่างการอัปเดตหรือลบเพื่อไม่ให้เขียนทับการเปลี่ยนแปลงของลูกค้ารายอื่น เนื่องจากความแตกต่างนี้ ไลบรารีของไคลเอ็นต์จะไม่อนุญาตให้คุณส่ง ETag ที่ไม่รัดกุมซึ่งมีคําขออัปเดตหรือลบ

ETag จะอยู่ใน 2 ตําแหน่งในการตอบกลับของเซิร์ฟเวอร์ ดังนี้

  • ในส่วนหัว HTTP ของ ETag
  • เป็นแอตทริบิวต์ gd:etag ในฟีด/รายการ

หากบริการรองรับเวอร์ชัน 2 ฟีดและออบเจ็กต์รายการแต่ละรายการจะมีเมธอด getEtag() เพื่อดึงค่าของ ETag

ไคลเอ็นต์ JavaScript รองรับการรวม ETag กับคําขอ 2 วิธี อย่างแรกคือออบเจ็กต์ opt_params ใหม่ ฟังก์ชัน get/update/insert ทั้งหมดในไลบรารีของไคลเอ็นต์เวอร์ชัน 2 จะมีพารามิเตอร์ opt_params ใหม่ ออบเจ็กต์นี้ใช้เพื่อระบุพารามิเตอร์ที่ไม่บังคับเมื่อส่งคําขอ สําหรับตอนนี้ 'etag' เป็นพารามิเตอร์ที่ไม่บังคับเพียงประเภทเดียวที่รองรับ (แต่อาจมีพารามิเตอร์อื่นๆ เพิ่มเข้ามาในอนาคต) ตัวอย่างเช่น คุณสามารถเพิ่ม ETag ในคําขอ GET ได้ ดังนี้

var opt_params = {};
opt_params['etag'] = 'ETAG GOES HERE';
service.getFeed(uri, successHandler, errorHandler, opt_params);

คุณยังเพิ่ม ETag ลงในฟีดหรือออบเจ็กต์รายการได้โดยตรง โดยเรียกใช้เมธอด setEtag() ในฟีด/รายการ

ดูข้อมูลเพิ่มเติมเกี่ยวกับ ETag ได้จากข้อมูลอ้างอิงโปรโตคอล GData

การใช้ ETag ในการดึงข้อมูล

ETag ช่วยลดแบนด์วิดท์และเวลาในการดําเนินการเมื่อดึงข้อมูล ETag อาจรวมอยู่ในคําขอ GET ที่มี If-None-Match header:

If-None-Match: ETAG GOES HERE

หาก ETag ตรงกับฟีดหรือรายการเวอร์ชันปัจจุบัน เซิร์ฟเวอร์จะตอบสนองด้วยการตอบกลับ 304 NOT MODIFIED และเนื้อความว่างเปล่า ไม่เช่นนั้น เซิร์ฟเวอร์จะตอบกลับด้วยการตอบกลับว่า 200 OK และฟีดหรือข้อมูลรายการ

คุณใช้ ETag ในไคลเอ็นต์ JavaScript ได้โดยรวมพารามิเตอร์ของ 'etag' เมื่อส่งคําขอ ดังนี้

var etag = feed.getEtag(); // Feed loaded from a previous request
var opt_params = {};
opt_params['etag'] = etag;
service.getFeed(feedUrl, successHandler, errorHandler, opt_params);

การดึงข้อมูลแบบมีเงื่อนไขทํางานร่วมกับ ETag ที่แข็งแรงและอ่อน หาก ETag ตรงกัน ระบบจะเรียกเครื่องจัดการข้อผิดพลาดด้วยการตอบสนอง 304 ดังนี้

function successHandler(feedRoot) {
  // 200 response
  // Update UI to display updates
}

function errorHandler(errorObj) {
  if (errorObj.cause.getStatus() == 304) {
    // 304 response, do nothing
  }
  // otherwise the response is some other error
}

ดูตัวอย่างการเรียกข้อมูลแบบมีเงื่อนไขโดยใช้ Blogger เพื่อดูตัวอย่างจริงของการใช้ ETag ในไคลเอ็นต์ JavaScript ตัวอย่างนี้จะได้รับแบบสํารวจจาก Blogger ในช่วงเวลา 5 วินาทีเพื่อหาอัปเดตในบล็อกของคุณ เมื่อมีการเปลี่ยนแปลง ตัวอย่างจะอัปเดตรายการโพสต์

การใช้ ETag เพื่ออัปเดตและลบข้อมูล

การใช้ ETag เกี่ยวกับคําขออัปเดต/ลบทําให้มั่นใจว่าไคลเอ็นต์จํานวนมากจะไม่เขียนทับการเปลี่ยนแปลงของกันและกันโดยไม่ตั้งใจ ในกรณีนี้ ETag จะรวมอยู่ในส่วนหัว If-Match ดังนี้

If-Match: ETAG GOES HERE

หาก ETag ในคําขอตรงกับ ETag บนเซิร์ฟเวอร์ การอัปเดต/ลบจะประสบความสําเร็จ แต่ ETag ที่ไม่ตรงกันจะบ่งชี้ว่ารายการดังกล่าวมีการเปลี่ยนแปลง และการอัปเดต/ลบล้มเหลว ในกรณีนี้ แอปพลิเคชันควรขออินสแตนซ์ใหม่ของข้อมูล แล้วลองอัปเดต/ลบอีกครั้ง

ในบางกรณี คุณอาจต้องการบังคับให้มีการเปลี่ยนแปลงข้อมูลโดยไม่คํานึงถึงการเปลี่ยนแปลงอื่นๆ ในรายการ ซึ่งทําได้โดยการส่ง * ไปยังส่วนหัวของ If-Match ดังนี้

If-Match: *

โปรดทราบว่าการดําเนินการนี้จะลบล้างการเปลี่ยนแปลงที่ทําโดยไคลเอ็นต์อื่นๆ ดังนั้นโปรดใช้อย่างระมัดระวัง

คุณจะอัปเดต/ลบรายการที่มี ETag ที่รัดกุมได้เท่านั้น การระบุ ETag ที่ไม่รัดกุมจะทําให้เกิดข้อผิดพลาด ไคลเอ็นต์ JavaScript จะไม่ตั้งค่า ETag ที่ไม่รัดกุมในการอัปเดตและลบคําขอเพื่อป้องกันกรณีนี้

มีการใช้ ETag เหมือนกับการดึงเงื่อนไข

function updateData(entry, service) {
  var etag = entry.getEtag();
  var opt_params = {};
  opt_params['etag'] = etag; // Or use '*' to force an update.
  service.updateEntry(successHandler, errorHandler, opt_params);
}

function successHandler(response) {
  // Successful update
}

function errorHandler(errorObj) {
  // ERROR - Update failed. Could be due to an ETag mismatch, but check the
  // error message to make sure. An ETag error will be in the format:
  // Mismatch: etags = ["Qnc-fTVSLyp7ImA9WxJbFEsDRAw."], version = [1249675665358000]
}

เมื่ออัปเดตแล้ว คุณจะระบุ ETag ได้ 2 ตําแหน่ง ดังนี้

  1. ในรายการ โดยใช้เมธอด getEtag() และ setEtag()
  2. ในส่วนหัว โดยใช้ออบเจ็กต์ opt_params (ดังที่แสดงด้านบน)

รายการที่โหลดจากคําขอ GET ก่อนหน้าจะมีชุดช่อง ETag อยู่แล้ว ดังนั้นการระบุ ETag เดียวกันในออบเจ็กต์ opt_params จึงเป็นสิ่งซ้ําซ้อน ในกรณีที่ระบุ ETag ทั้งในส่วนเนื้อหาของรายการและใน opt_params ETag ใน opt_params จะมีลําดับความสําคัญเหนือกว่า อาจทําให้สับสนเล็กน้อย ดังนั้นหากคุณพบปัญหาเกี่ยวกับการอัปเดตแบบมีเงื่อนไข อย่าลืมตรวจสอบ ETag ทั้งในรายการและออบเจ็กต์ opt_params

google.gdata.Entry ของชั้นเรียนจะมีเมธอด updateEntry() และ deleteEntry() ของตัวเองเพื่อให้ทําได้ง่ายขึ้น หากคลาสรายการมี ETag อยู่แล้ว คุณไม่จําเป็นต้องเพิ่มลงในคําขอ ไลบรารีของไคลเอ็นต์จะดําเนินการดังกล่าวให้คุณโดยอัตโนมัติ เช่น

// entry was loaded from a previous request.  No need to specify
// an ETag in opt_params here, it is added automatically.
entry.deleteEntry(successHandler, errorHandler);

วิธีนี้จะช่วยให้คุณได้รับประโยชน์จาก ETag โดยไม่ต้องกังวลว่าตั้งค่าอย่างถูกต้อง อย่างไรก็ตาม หากต้องการบังคับให้อัปเดตโดยใช้ '*' คุณต้องรวมออบเจ็กต์ opt_params ที่มี 'etag' = '*' เสมอ

คุณดูการอัปเดตแบบมีเงื่อนไขได้ในการอัปเดตแบบมีเงื่อนไขใน Contacts ตัวอย่างนี้จะสร้างกลุ่มรายชื่อติดต่อทดสอบก่อนซึ่งจะสร้างข้อมูลทั้งหมดที่ตัวอย่างนี้ใช้ คุณสามารถลบกลุ่มรายชื่อติดต่อนี้เมื่อใช้ตัวอย่างเสร็จแล้ว จากนั้นตัวอย่างจะโหลด iframe 2 รายการที่มีเนื้อหาจากกลุ่มรายชื่อติดต่อ คุณสามารถทําการอัปเดตใน iframe หนึ่งและดูว่าอัปเดตมีผลอย่างไรใน iframe อื่น ไปยังตัวอย่างเพื่อดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีใช้

ตัวอย่าง

ข้อมูลอ้างอิง

สําหรับข้อมูลอ้างอิงเกี่ยวกับคลาสและวิธีการที่ไลบรารีของไคลเอ็นต์มีให้ โปรดดูเอกสารอ้างอิงไลบรารีของไคลเอ็นต์ JavaScript (ในรูปแบบ JSdoc)

กลับไปด้านบน