ผู้เขียน: Zhui Feng
ใช้ ASP ในการเขียนแอปพลิเคชันเว็บไซต์มาเป็นเวลานาน ย่อมหลีกเลี่ยงไม่ได้ที่คุณจะพบปัญหาต่างๆ เช่น การอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ หากคุณต้องการใช้ฟังก์ชัน "หนึ่งดาวต่อวัน" คล้ายกับที่ชุมชนเสมือน NetEase มอบให้ในชุมชนของคุณเอง คุณต้องจัดเตรียมฟังก์ชันให้ชาวเน็ตอัปโหลดรูปภาพ ในการอัปโหลดไฟล์รูปภาพไปยังเซิร์ฟเวอร์ คุณสามารถใช้ส่วนประกอบการอัปโหลดไฟล์ฟรีต่างๆ ได้ แม้ว่าจะมีประสิทธิภาพมาก แต่ในหลายกรณี เราสามารถใช้เฉพาะพื้นที่ฟรีที่รองรับ ASP หรือเช่าพื้นที่เสมือนของผู้อื่นเท่านั้น เป็นไปไม่ได้เลยที่เราจะสามารถใช้องค์ประกอบการอัปโหลดไฟล์ได้ สำหรับกรณีที่ 2 เรายังต้องจ่าย "เงิน" จำนวนมากด้วย หากคุณไม่มีโฮสต์เสมือนของคุณเอง คุณสามารถติดตั้งส่วนประกอบที่คุณต้องการบนเซิร์ฟเวอร์ได้อย่างง่ายดาย สถานการณ์นี้อยู่ไกลเกินเอื้อมสำหรับคนส่วนใหญ่ แล้วเราทำอะไรไม่ได้เลยเหรอ? ฮ่าๆ คำตอบคือใช่ (ใช่แน่นอน ไม่งั้นเขียนบทความนี้ไม่ได้) ลองใช้โค้ด ASP บริสุทธิ์เพื่อใช้ฟังก์ชันการอัปโหลดรูปภาพและบันทึกลงในฐานข้อมูล (นอกจากนี้ เรายังใช้ฟังก์ชันการแสดงรูปภาพในฐานข้อมูลบนหน้าเว็บด้วย)
ขั้นแรก เรามาทำความคุ้นเคยกับวิธีการของวัตถุที่เราจะใช้กันก่อน โดยทั่วไปเราใช้วัตถุคำขอเพื่อรับข้อมูลที่ส่งผ่านจากหน้าก่อนหน้า ในทำนองเดียวกัน เรายังสามารถใช้อ็อบเจ็กต์ Request เพื่อรับข้อมูลไฟล์ที่อัพโหลดได้ วิธีที่ใช้คือ Request.BinaryRead() วิธีที่เราใช้อ่านข้อมูลภาพจากฐานข้อมูลและแสดงบนหน้าเว็บคือ:
คำขอ BinaryWrite() เมื่อเราได้รับข้อมูลรูปภาพและบันทึกลงในฐานข้อมูล เราจะไม่สามารถใช้คำสั่ง Insert เพื่อดำเนินการฐานข้อมูลได้โดยตรง เราต้องใช้วิธี AppendChunk ของ ADO ในทำนองเดียวกัน เพื่ออ่านข้อมูลรูปภาพในฐานข้อมูล เราต้องใช้ วิธีการ GetChunk ไวยากรณ์เฉพาะของแต่ละวิธีมีดังนี้:
*คำขอ ไวยากรณ์ BinaryRead:
Variant=Request.BinaryRead(นับ)
พารามิเตอร์
ตัวแปร
ค่าส่งคืนเก็บข้อมูลที่อ่านจากไคลเอนต์
นับ
ระบุจำนวนข้อมูลที่จะอ่านจากไคลเอ็นต์ ค่านี้น้อยกว่าหรือเท่ากับจำนวนข้อมูลที่ได้รับโดยใช้เมธอด Request.TotalBytes
*Request.BinaryWrite ไวยากรณ์:
คำขอ BinaryWritedata
พารามิเตอร์
ข้อมูล
แพ็กเก็ตที่จะเขียนไปยังเบราว์เซอร์ไคลเอ็นต์
*คำขอ ไวยากรณ์ TotalBytes:
ตัวแปร = คำขอ TotalBytes
พารามิเตอร์
ตัวแปร
ส่งกลับจำนวนไบต์ของข้อมูลที่อ่านจากไคลเอนต์
*ไวยากรณ์ AppendChunk ผนวกข้อมูลเข้ากับข้อความขนาดใหญ่ ข้อมูลไบนารี ฟิลด์ หรือวัตถุพารามิเตอร์
object.AppendChunkData
พารามิเตอร์
objectField หรือวัตถุพารามิเตอร์
ประเภทตัวแปรข้อมูล ซึ่งมีข้อมูลที่ต่อท้ายออบเจ็กต์
คำอธิบาย ใช้เมธอด AppendChunk ของออบเจ็กต์ฟิลด์หรือพารามิเตอร์เพื่อกรอกข้อมูลไบนารีหรืออักขระแบบยาวลงในออบเจ็กต์ เมื่อหน่วยความจำระบบมีจำกัด คุณสามารถใช้เมธอด AppendChunk เพื่อดำเนินการบางอย่างแต่ไม่ใช่การดำเนินการทั้งหมดกับค่าจำนวนเต็มยาว
*ไวยากรณ์ GetChunk ส่งคืนเนื้อหาทั้งหมดหรือบางส่วนของข้อความขนาดใหญ่หรือวัตถุฟิลด์ข้อมูลไบนารี
ตัวแปร = field.GetChunk (ขนาด)
ค่าที่ส่งคืนจะส่งกลับประเภทตัวแปร
พารามิเตอร์
กำหนดขนาดนิพจน์จำนวนเต็มยาว เท่ากับจำนวนไบต์หรืออักขระที่จะดึงข้อมูล
คำอธิบาย ใช้เมธอด GetChunk ของอ็อบเจ็กต์ Field เพื่อดึงข้อมูลไบนารีหรืออักขระแบบยาวบางส่วนหรือทั้งหมด เมื่อหน่วยความจำระบบมีจำกัด คุณสามารถใช้เมธอด GetChunk เพื่อประมวลผลค่าจำนวนเต็มยาวบางส่วนแต่ไม่ใช่ทั้งหมด
ข้อมูลที่ส่งคืนโดยการเรียก GetChunk จะถูกกำหนดให้กับ "ตัวแปร" หาก Size มากกว่าข้อมูลที่เหลือ
GetChunk เพียงส่งคืนข้อมูลที่เหลือโดยไม่ต้องเติม "ตัวแปร" ด้วยช่องว่าง ถ้าสนามว่างแล้ว
วิธีการ GetChunk ส่งคืนค่า Null
การโทร GetChunk ครั้งต่อไปแต่ละครั้งจะดึงข้อมูลโดยเริ่มจากจุดที่การโทร GetChunk ก่อนหน้านี้ค้างไว้ อย่างไรก็ตาม หากคุณดึงข้อมูลจากเขตข้อมูลหนึ่ง แล้วตั้งค่าหรืออ่านค่าของเขตข้อมูลอื่นในระเบียนปัจจุบัน ADO จะถือว่าข้อมูลถูกดึงมาจากเขตข้อมูลแรก ถ้ามีการเรียกวิธีการ GetChunk อีกครั้งในฟิลด์แรก ADO จะตีความการเรียกเป็นการดำเนินการ GetChunk ใหม่ และเริ่มอ่านจากจุดเริ่มต้นของเรกคอร์ด ถ้าวัตถุชุดระเบียนอื่นไม่ใช่สำเนาของวัตถุชุดระเบียนแรก การเข้าถึงเขตข้อมูลในนั้นจะไม่ทำให้การดำเนินการ GetChunk เสียหาย
ถ้าบิต adFldLong ในคุณสมบัติแอตทริบิวต์ของวัตถุเขตข้อมูลถูกตั้งค่าเป็น True คุณสามารถใช้วิธี GetChunk บนเขตข้อมูลได้
หากไม่มีเรกคอร์ดปัจจุบันเมื่อใช้วิธี Getchunk บนวัตถุฟิลด์ ข้อผิดพลาด 3021 (ไม่มีเรกคอร์ดปัจจุบัน) จะถูกสร้างขึ้น
ต่อไป เราจะออกแบบฐานข้อมูลของเรา จากการทดสอบโครงสร้างฐานข้อมูลของเราจะเป็นดังนี้ (access2000):
ชื่อฟิลด์ ประเภท คำอธิบาย รหัส หมายเลขอัตโนมัติ ค่าคีย์หลัก
วัตถุ img OLE ใช้เพื่อบันทึกข้อมูลรูปภาพ
สำหรับ MSSQLServer7 โครงสร้างที่เกี่ยวข้องจะเป็นดังนี้:
ชื่อฟิลด์ ประเภท คำอธิบาย id int (Identity) ค่าคีย์หลัก
รูปภาพ img ใช้เพื่อบันทึกข้อมูลรูปภาพ
ตอนนี้เราเริ่มเขียนส่วนอัพโหลดของโค้ด ASP ของเราอย่างเป็นทางการ ขั้นแรก เรามีอินเทอร์เฟซการอัปโหลดที่จัดเตรียมไว้ให้กับผู้ใช้ ซึ่งอนุญาตให้ผู้ใช้เลือกรูปภาพที่จะอัปโหลด รหัสดังต่อไปนี้ (upload.htm):
<html>
<ร่างกาย>
<ศูนย์>
<ชื่อฟอร์ม = "mainForm" enctype = "multipart/form-data" action = "process.asp" method = post >
<inputtype=filename=mefile><br>
<inputtype=submitname=okvalue="ตกลง">
</แบบฟอร์ม>
</ศูนย์>
</ร่างกาย>
</html>
โปรดทราบว่า enctype="multipart/form-data" ต้องมีแอตทริบิวต์นี้ในแบบฟอร์ม มิฉะนั้น จะไม่ได้รับข้อมูลที่อัปโหลด ต่อไป เราจำเป็นต้องดำเนินการประมวลผลที่จำเป็นกับข้อมูลที่ได้รับจากเบราว์เซอร์ใน process.asp เนื่องจากข้อมูลที่เราได้รับใน process.asp ไม่เพียงแต่มีข้อมูลของรูปภาพที่อัปโหลดที่เราต้องการเท่านั้น แต่ยังมีข้อมูลที่ไร้ประโยชน์อื่น ๆ ที่เราต้องการด้วย เพื่อกำจัดข้อมูลที่ซ้ำซ้อนและบันทึกข้อมูลภาพที่ประมวลผลลงในฐานข้อมูล ที่นี่เราใช้ access2000 เป็นตัวอย่าง รหัสเฉพาะมีดังนี้ (process.asp):
-
response.buffer=true
formsize=request.totalbytes
formdata=request.binaryread(ขนาดฟอร์ม)
bncrlf=chrB(13)&chrB(10)
ตัวแบ่ง=leftB(formdata,clng(instrb(formdata,bncrlf))-1)
datastart=instrb(formdata,bncrlf&bncrlf)+4
dataend=instrb(datastart+1,formdata,divider)-datastart
mydata=midb(formdata,datastart,dataend)
setconnGraph=server.CreateObject("ADODB.connection")
connGraph.ConnectionString="driver={MicrosoftAccessDriver(*.mdb)};DBQ="&server.MapPath("images.mdb")&";uid=;PWD=;"
connGraph.เปิด
setrec=server.createobject("ADODB.recordset")
rec.Open"SELECT*FROM[images]whereidisnull",connGraph,1,3
rec.เพิ่มใหม่
rec("img").appendchunkmydata
อัพเดทอีกครั้ง
rec.ปิด
setrec=ไม่มีอะไร
setconnGraph=ไม่มีอะไร
-
เอาล่ะ ตอนนี้เราได้บันทึกภาพที่อัพโหลดลงในฐานข้อมูลชื่อ images.mdb งานที่เหลือคือการแสดงข้อมูลภาพในฐานข้อมูลบนหน้าเว็บ โดยทั่วไปใน HTML แท็ก <IMG> ใช้เพื่อแสดงรูปภาพ นั่นคือ <IMGSRC="image path"> แต่รูปภาพของเราจะถูกบันทึกไว้ในฐานข้อมูล อะไรคือ "เส้นทางรูปภาพ" ฮ่าฮ่า จริงๆ แล้ว นอกจากการระบุเส้นทางแล้ว คุณลักษณะ SRC นี้ยังสามารถใช้ในลักษณะนี้ได้ด้วย:
<IMGSRC="showimg.asp?id=xxx">
ดังนั้นสิ่งที่เราต้องทำคืออ่านข้อมูลที่ผ่านการรับรองจากฐานข้อมูลใน showimg.asp แล้วส่งคืนไปยังแอตทริบิวต์ SRC รหัสเฉพาะมีดังนี้ (showimg.asp):
-
setconnGraph=server.CreateObject("ADODB.connection")
connGraph.ConnectionString = "ไดรเวอร์ = {MicrosoftAccessDriver (*.mdb)}; DBQ = "&
server.MapPath("images.mdb")&";uid=;PWD=;"
connGraph.เปิด
setrec=server.createobject("ADODB.recordset")
strsql="selectimgfromimageswhereid="&trim(คำขอ("id"))
rec.openstrsql,connGraph,1,1
Response.ContentType="รูปภาพ/*"
Response.BinaryWriterec("img").getChunk(7500000)
rec.ปิด
setrec=ไม่มีอะไร
setconnGraph=ไม่มีอะไร
-
โปรดทราบว่าต้องระบุ Response.ContentType="image/*" ก่อนที่จะส่งออกไปยังเบราว์เซอร์
เพื่อให้แสดงภาพได้ตามปกติ
สิ่งสุดท้ายที่ควรทราบคือการประมวลผลใน process.asp ของฉันไม่ได้คำนึงถึงว่ามีข้อมูลอื่นในหน้าแรก (upload.htm) เช่น <INPUT type=tesxt name=userid> ฯลฯ หาก มีรายการเหล่านี้ process.asp ของคุณควรใส่ใจกับการประมวลผลข้อมูลที่ไม่จำเป็น