Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

การอัพโหลดไฟล์ด้วย Rails และ Shrine

มีอัญมณีที่อัปโหลดไฟล์มากมายเช่น CarrierWave, Paperclip และ Dragonfly เป็นต้น พวกเขาทั้งหมดมีลักษณะเฉพาะของพวกเขา และคุณอาจเคยใช้อัญมณีเหล่านี้อย่างน้อยหนึ่งชิ้น

อย่างไรก็ตาม วันนี้ฉันอยากจะแนะนำวิธีการแก้ปัญหาที่ค่อนข้างใหม่แต่เจ๋งมากที่เรียกว่า Shrine ซึ่งสร้างโดย Janko Marohnić ตรงกันข้ามกับอัญมณีอื่นๆ ที่คล้ายคลึงกัน มันมีวิธีการแบบแยกส่วน หมายความว่าทุกฟีเจอร์ถูกบรรจุเป็นโมดูล (หรือ ปลั๊กอิน ในคำศัพท์ของศาลเจ้า) ต้องการสนับสนุนการตรวจสอบหรือไม่ เพิ่มปลั๊กอิน ต้องการประมวลผลไฟล์หรือไม่? เพิ่มปลั๊กอิน! ฉันชอบแนวทางนี้มากเพราะช่วยให้คุณควบคุมฟีเจอร์ที่จะใช้งานได้สำหรับรุ่นใดได้อย่างง่ายดาย

ในบทความนี้ผมจะแสดงวิธีการ:

  • รวม Shrine เข้ากับแอปพลิเคชัน Rails
  • กำหนดค่า (ทั่วโลกและต่อผู้อัปโหลด)
  • เพิ่มความสามารถในการอัปโหลดไฟล์
  • ประมวลผลไฟล์
  • เพิ่มกฎการตรวจสอบ
  • จัดเก็บข้อมูลเมตาเพิ่มเติมและใช้พื้นที่จัดเก็บไฟล์บนระบบคลาวด์ด้วย Amazon S3

ซอร์สโค้ดสำหรับบทความนี้มีอยู่ใน GitHub

สามารถดูการสาธิตการทำงานได้ที่นี่

บูรณาการศาลเจ้า

ในการเริ่มต้น ให้สร้างแอปพลิเคชัน Rails ใหม่โดยไม่มีชุดทดสอบเริ่มต้น:

เปิดตัว FileGuru -T ใหม่

ฉันจะใช้ Rails 5 สำหรับการสาธิตนี้ แต่แนวคิดส่วนใหญ่ใช้กับเวอร์ชัน 3 และ 4 ด้วยเช่นกัน

วางอัญมณีศาลเจ้าลงใน Gemfile ของคุณ:

อัญมณี "ศาลเจ้า"

จากนั้นเรียกใช้:

การติดตั้งมัด

ตอนนี้เราต้องการโมเดลที่จะเรียกว่า Photo . Shrine เก็บข้อมูลที่เกี่ยวข้องกับไฟล์ทั้งหมดในคอลัมน์ข้อความพิเศษที่ลงท้ายด้วย _data คำต่อท้าย สร้างและใช้การย้ายข้อมูลที่เกี่ยวข้อง:

rails g model ชื่อภาพ:string image_data:textrails db:migrate

โปรดทราบว่าสำหรับ Rails เวอร์ชันเก่า คำสั่งหลังควรเป็น:

rake db:migrate

ตัวเลือกการกำหนดค่าสำหรับ Shrine สามารถตั้งค่าได้ทั้งแบบสากลและแบบต่อรุ่น แน่นอนว่าการตั้งค่าส่วนกลางเสร็จสิ้นภายในไฟล์ตัวเริ่มต้น ฉันจะเชื่อมต่อไฟล์ที่จำเป็นและ ปลั๊กอิน . ปลั๊กอินถูกใช้ใน Shrine เพื่อแยกส่วนการทำงานออกเป็นโมดูลแยกกัน ทำให้คุณสามารถควบคุมคุณสมบัติทั้งหมดที่มีได้อย่างเต็มที่ ตัวอย่างเช่น มีปลั๊กอินสำหรับการตรวจสอบ การประมวลผลภาพ การแคชไฟล์แนบ และอื่นๆ อีกมากมาย

ในตอนนี้ ให้เพิ่มปลั๊กอินสองตัว:ตัวหนึ่งรองรับ ActiveRecord และอีกตัวสำหรับตั้งค่าการบันทึก พวกเขาจะรวมอยู่ในทั่วโลก ตั้งค่าที่เก็บข้อมูลระบบไฟล์ด้วย:

config/initializers/shrine.rb

require "shrine"require "shrine/storage/file_system"Shrine.plugin :activerecordShrine.plugin :logging, logger:Rails.loggerShrine.storages ={ แคช:Shrine::Storage::FileSystem.new("public", คำนำหน้า:"uploads/cache"), store:Shrine::Storage::FileSystem.new("public", prefix:"uploads/store"),}

Logger จะแสดงข้อมูลการดีบักบางอย่างภายในคอนโซลเพื่อให้คุณบอกว่าใช้เวลาประมวลผลไฟล์นานเท่าใด สิ่งนี้มีประโยชน์

2015-10-09T20:06:06.676Z #25602:STORE[แคช] ImageUploader[:avatar] ผู้ใช้[29543] 1 ไฟล์ (0.1 วินาที)2015-10-09T20:06:06.854Z #25602:กระบวนการ[ store]:ImageUploader[:avatar] User[29543] 1-3 files (0.22s)2015-10-09T20:06:07.133Z #25602:DELETE[destroyed]:ImageUploader[:avatar] User[29543] 3 ไฟล์ ( 0.07s)

ไฟล์ที่อัปโหลดทั้งหมดจะถูกเก็บไว้ใน สาธารณะ/อัปโหลด ไดเรกทอรี ฉันไม่ต้องการติดตามไฟล์เหล่านี้ใน Git ดังนั้นให้แยกโฟลเดอร์นี้:

.gitignore

สาธารณะ/อัปโหลด

ตอนนี้สร้างคลาส "ตัวอัปโหลด" พิเศษที่จะโฮสต์การตั้งค่าเฉพาะรุ่น สำหรับตอนนี้ คลาสนี้จะว่าง:

models/image_uploader.rb

คลาส ImageUploader  

สุดท้าย รวมคลาสนี้ไว้ใน Photo รุ่น:

รุ่น/photo.rb

รวม ImageUploader[:image]

[:image] เพิ่มแอตทริบิวต์เสมือนที่จะใช้เมื่อสร้างแบบฟอร์ม บรรทัดด้านบนสามารถเขียนใหม่เป็น:

 รวม ImageUploader.attachment(:image) # หรือรวม ImageUploader::Attachment.new(:image) 

ดี! ตอนนี้โมเดลได้รับการติดตั้งฟังก์ชันของ Shrine แล้ว และเราสามารถไปยังขั้นตอนต่อไปได้

ตัวควบคุม มุมมอง และเส้นทาง

สำหรับจุดประสงค์ของการสาธิตนี้ เราจำเป็นต้องมีตัวควบคุมเพียงตัวเดียวในการจัดการรูปภาพ index หน้าจะทำหน้าที่เป็นรูท:

pages_controller.rb

คลาส PhotosController  

มุมมอง:

views/photos/index.html.erb

รูปภาพ

<%=link_to 'เพิ่มรูปภาพ', new_photo_path %><%=render @photos %>

เพื่อแสดงผล @photos อาร์เรย์ ต้องการบางส่วน:

views/photos/_photo.html.erb

<% ถ้า photo.image_data? %> <%=image_tag photo.image_url %> <% สิ้นสุด %>

<%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>

image_data? เป็นวิธีการที่นำเสนอโดย ActiveRecord ที่ตรวจสอบว่าบันทึกมีภาพหรือไม่

image_url เป็นวิธีการของ Shrine ที่คืนค่าเส้นทางไปยังภาพต้นฉบับ แน่นอน การแสดงภาพขนาดย่อเล็กๆ แทนจะดีกว่ามาก แต่เราจะดูแลในภายหลัง

เพิ่มเส้นทางที่จำเป็นทั้งหมด:

config/routes.rb

 ทรัพยากร :photos เท่านั้น:[:new, :create, :index, :edit, :update] root 'photos#index'

แค่นี้เอง รากฐานเสร็จแล้ว และเราสามารถไปยังส่วนที่น่าสนใจได้!

อัพโหลดไฟล์

ในส่วนนี้ ฉันจะแสดงวิธีเพิ่มฟังก์ชันการทำงานเพื่ออัปโหลดไฟล์จริง การทำงานของตัวควบคุมนั้นง่ายมาก:

photos_controller.rb

def new @photo =Photo.newenddef create @photo =Photo.new(photo_params) ถ้า @photo.save flash[:success] ='Photo added!' redirect_to photos_path อื่น ๆ ทำให้สิ้นสุด 'ใหม่'

Gotcha เพียงอย่างเดียวคือสำหรับพารามิเตอร์ที่แข็งแกร่ง คุณต้องอนุญาต image แอตทริบิวต์เสมือน ไม่ใช่ image_data .

photos_controller.rb

privatedef photo_params params.require(:photo).permit(:title, :image)end

สร้าง new มุมมอง:

views/photos/new.html.erb

เพิ่มรูปภาพ

<%=แสดง 'แบบฟอร์ม' %>

บางส่วนของแบบฟอร์มก็ไม่สำคัญเช่นกัน:

views/photos/_form.html.erb

<%=form_for @photo do |f| %> <%=แสดงผล "แชร์/ข้อผิดพลาด" วัตถุ:@photo %> <%=f.label :title %> <%=f.text_field :title %> <%=f.label :image %> <% =f.file_field :image %> <%=f.submit %><% end %>

ย้ำอีกครั้งว่าเรากำลังใช้ image แอตทริบิวต์ ไม่ใช่ image_data .

สุดท้าย เพิ่มอีกบางส่วนเพื่อแสดงข้อผิดพลาด:

views/shared/_errors.html.erb

<ก่อน><% ถ้า object.errors.any? %>

พบข้อผิดพลาดต่อไปนี้:

    <% object.errors.full_messages.each do |message| %>
  • <%=ข้อความ %>
  • <% สิ้นสุด %>
<% สิ้นสุด %>

เท่านี้ก็เรียบร้อย—คุณสามารถเริ่มอัปโหลดภาพได้ทันที

การตรวจสอบความถูกต้อง

แน่นอนว่ายังต้องทำงานอีกมากเพื่อให้แอปสาธิตเสร็จสมบูรณ์ ปัญหาหลักคือผู้ใช้สามารถอัปโหลดไฟล์ประเภทใดก็ได้ที่มีขนาดใดก็ได้ ซึ่งไม่ได้ยอดเยี่ยมเป็นพิเศษ ดังนั้น เพิ่มปลั๊กอินอื่นเพื่อรองรับการตรวจสอบ:

config/inititalizers/shrine.rb

Shrine.plugin :validation_helpers

ตั้งค่าตรรกะการตรวจสอบสำหรับ ImageUploader :

models/image_uploader.rb

Attacher.validate do validate_max_size 1.megabyte, message:" is too large (max is 1 MB)" validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png']end

ฉันอนุญาตให้อัปโหลดเฉพาะรูปภาพ JPG และ PNG ที่น้อยกว่า 1MB ปรับกฎเหล่านี้ตามที่เห็นสมควร

ประเภท MIME

สิ่งสำคัญอีกประการที่ควรทราบคือโดยค่าเริ่มต้น Shrine จะกำหนดประเภท MIME ของไฟล์โดยใช้ส่วนหัว HTTP ประเภทเนื้อหา ส่วนหัวนี้ถูกส่งผ่านโดยเบราว์เซอร์และตั้งค่าตามนามสกุลของไฟล์เท่านั้น ซึ่งไม่เป็นที่ต้องการเสมอไป

หากคุณต้องการกำหนดประเภท MIME ตามเนื้อหาของไฟล์ ให้ใช้ปลั๊กอินที่เรียกว่า determine_mime_type ฉันจะรวมไว้ในคลาสตัวอัปโหลด เนื่องจากรุ่นอื่นๆ อาจไม่ต้องการฟังก์ชันนี้:

models/image_uploader.rb

ปลั๊กอิน :determine_mime_type

ปลั๊กอินนี้จะใช้ยูทิลิตี้ไฟล์ของ Linux เป็นค่าเริ่มต้น

แคชรูปภาพที่แนบมา

ปัจจุบันเมื่อผู้ใช้ส่งแบบฟอร์มที่มีข้อมูลไม่ถูกต้อง แบบฟอร์มจะแสดงอีกครั้งโดยมีข้อผิดพลาดที่แสดงไว้ด้านบน อย่างไรก็ตาม ปัญหาคือ รูปภาพที่แนบมาจะสูญหาย และผู้ใช้จะต้องเลือกรูปภาพดังกล่าวอีกครั้ง ซึ่งแก้ไขได้ง่ายมากโดยใช้ปลั๊กอินอื่นที่เรียกว่า cached_attachment_data:

models/image_uploader.rb

ปลั๊กอิน :cached_attachment_data

เพียงเพิ่มฟิลด์ที่ซ่อนอยู่ในแบบฟอร์มของคุณ

views/photos/_form.html.erb

<%=f.hidden_field :image, ค่า:@photo.cached_image_data %><%=f.label :image %><%=f.file_field :image %>

การแก้ไขรูปภาพ

ตอนนี้สามารถอัพโหลดรูปภาพได้ แต่ไม่มีวิธีแก้ไข ดังนั้นมาแก้ไขทันที การกระทำของผู้ควบคุมที่เกี่ยวข้องนั้นค่อนข้างเล็กน้อย:

photos_controller.rb

def edit @photo =Photo.find(params[:id])enddef update @photo =Photo.find(params[:id]) if @photo.update_attributes(photo_params) flash[:success] ='แก้ไขรูปภาพแล้ว !' redirect_to photos_path อื่น ๆ ทำให้ 'แก้ไข' สิ้นสุด

_formเหมือนกัน บางส่วนจะถูกนำไปใช้:

views/photos/edit.html.erb

แก้ไขรูปภาพ

<%=แสดง 'แบบฟอร์ม' %>

ดีแต่ยังไม่พอ:ผู้ใช้ยังคงไม่สามารถลบภาพที่อัปโหลดได้ ในการอนุญาตนี้ เราจะต้อง—คาดเดาอะไร—ปลั๊กอินอื่น: 

models/image_uploader.rb

ปลั๊กอิน :remove_attachment

ใช้แอตทริบิวต์เสมือนที่เรียกว่า :remove_image ให้อนุญาตภายในคอนโทรลเลอร์:

photos_controller.rb

def photo_params params.require(:photo).permit(:title, :image, :remove_image) สิ้นสุด

ตอนนี้เพียงแค่แสดงช่องทำเครื่องหมายเพื่อลบรูปภาพหากบันทึกมีสิ่งที่แนบมา:

views/photos/_form.html.erb

<% ถ้า @photo.image_data? %> ลบไฟล์แนบ:<%=f.check_box :remove_image %><% end %>

การสร้างภาพขนาดย่อ

ขณะนี้เราแสดงภาพต้นฉบับซึ่งไม่ใช่วิธีที่ดีที่สุดสำหรับการแสดงตัวอย่าง:รูปภาพอาจมีขนาดใหญ่และใช้พื้นที่มากเกินไป แน่นอน คุณสามารถใช้ CSS width และ height คุณลักษณะ แต่นั่นเป็นความคิดที่ไม่ดีเช่นกัน คุณเห็นไหมว่าแม้ว่ารูปภาพจะถูกตั้งค่าให้มีขนาดเล็กโดยใช้สไตล์ แต่ผู้ใช้ก็ยังต้องดาวน์โหลดไฟล์ต้นฉบับซึ่งอาจมีขนาดใหญ่มาก

ดังนั้นจึงเป็นการดีกว่ามากที่จะสร้างภาพตัวอย่างขนาดเล็กบนฝั่งเซิร์ฟเวอร์ระหว่างการอัปโหลดครั้งแรก สิ่งนี้เกี่ยวข้องกับสองปลั๊กอินและสองอัญมณีเพิ่มเติม ประการแรก วางอัญมณี:

อัญมณี "image_processing" อัญมณี "mini_magick", ">=4.3.5"

Image_processing เป็นอัญมณีพิเศษที่สร้างขึ้นโดยผู้เขียน Shrine นำเสนอวิธีการช่วยเหลือระดับสูงเพื่อจัดการรูปภาพ ในทางกลับกัน อัญมณีนี้อาศัย mini_magick ซึ่งเป็นเครื่องห่อหุ้ม Ruby สำหรับ ImageMagick อย่างที่คุณเดาได้ คุณจะต้องใช้ ImageMagick ในระบบของคุณเพื่อเรียกใช้การสาธิตนี้

ติดตั้งอัญมณีใหม่เหล่านี้:

การติดตั้งมัด

ตอนนี้รวมปลั๊กอินพร้อมกับการอ้างอิง:

models/image_uploader.rb

ต้องการ "image_processing/mini_magick" คลาส ImageUploader  

การประมวลผลคือปลั๊กอินที่ช่วยให้เราจัดการรูปภาพได้ (เช่น ลดขนาด หมุน แปลงเป็นรูปแบบอื่น เป็นต้น) ในทางกลับกัน เวอร์ชันต่างๆ ช่วยให้เรามีรูปภาพในรูปแบบต่างๆ สำหรับการสาธิตนี้ สองเวอร์ชันจะถูกเก็บไว้:"ดั้งเดิม" และ "นิ้วหัวแม่มือ" (ปรับขนาดเป็น 300x300 )

นี่คือรหัสสำหรับประมวลผลรูปภาพและจัดเก็บสองเวอร์ชัน:

รุ่น/image_uploader.rb

คลาส ImageUploader <กระบวนการ Shrine(:store) ทำ |io, บริบท| { ต้นฉบับ:io, thumb:resize_to_limit!(io.download, 300, 300) } สิ้นสุด

resize_to_limit! เป็นวิธีการที่ให้ไว้โดย image_processing gem มันย่อขนาดรูปภาพให้เหลือ 300x300 ถ้ามันใหญ่กว่าและไม่ทำอะไรเลยถ้ามันเล็กกว่า ยิ่งไปกว่านั้น ยังรักษาอัตราส่วนภาพตามต้นฉบับ

ตอนนี้เมื่อแสดงรูปภาพ คุณเพียงแค่ใส่ :original หรือ :thumb อาร์กิวเมนต์ของ image_url วิธีการ:

views/photos/_photo.html.erb

<% ถ้า photo.image_data? %> <%=image_tag photo.image_url(:thumb) %> <% สิ้นสุด %>

<%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>

เดียวกันสามารถทำได้ภายในแบบฟอร์ม:

views/photos/_form.html.erb

<% ถ้า @photo.image_data? %> <%=image_tag @photo.image_url(:thumb) %> ลบไฟล์แนบ:<%=f.check_box :remove_image %><% สิ้นสุด %>

หากต้องการลบไฟล์ที่ประมวลผลโดยอัตโนมัติหลังจากอัปโหลดเสร็จแล้ว คุณสามารถเพิ่มปลั๊กอินชื่อ delete_raw:

models/image_uploader.rb

ปลั๊กอิน :delete_raw

ข้อมูลเมตาของรูปภาพ

นอกเหนือจากการแสดงภาพจริงแล้ว คุณยังสามารถดึงข้อมูลเมตาของภาพได้อีกด้วย ตัวอย่างเช่น ให้แสดงขนาดของภาพถ่ายต้นฉบับและประเภท MIME:

views/photos/_photo.html.erb

<% ถ้า photo.image_data? %> <%=image_tag photo.image_url(:thumb) %>

ขนาด <%=photo.image[:original].size %> ไบต์
ประเภท MIME <%=photo.image[:original] mime_type %>

<% end %>

<%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>

แล้วขนาดของมันล่ะ? น่าเสียดาย ที่ไม่ได้จัดเก็บไว้ตามค่าเริ่มต้น แต่เป็นไปได้ด้วยปลั๊กอินชื่อ store_dimensions

ขนาดของรูปภาพ

ปลั๊กอิน store_dimensions อาศัย fastimage gem ดังนั้นให้เชื่อมต่อทันที:

อัญมณี 'fastimage'

อย่าลืมวิ่ง:

การติดตั้งมัด

ตอนนี้เพียงแค่รวมปลั๊กอิน:

models/image_uploader.rb

ปลั๊กอิน :store_dimensions

และแสดงขนาดโดยใช้width และ height วิธีการ:

views/photos/_photo.html.erb

<% ถ้า photo.image_data? %> <%=image_tag photo.image_url(:thumb) %>

ขนาด <%=photo.image[:original].size %> ไบต์
ประเภท MIME <%=photo.image[:original] mime_type %>
ขนาด <%="#{photo.image[:original].width}x#{photo.image[:original].height}" %>

<% สิ้นสุด %>

<%=photo.title %> | <%=link_to 'Edit', edit_photo_path(photo) %>

นอกจากนี้ยังมี dimensions เมธอดที่ส่งคืนอาร์เรย์ที่มีความกว้างและความสูง (เช่น [500, 750] )

ย้ายไปยังคลาวด์

นักพัฒนามักเลือกบริการคลาวด์เพื่อโฮสต์ไฟล์ที่อัปโหลด และ Shrine ก็นำเสนอความเป็นไปได้ดังกล่าว ในส่วนนี้ ฉันจะแสดงวิธีอัปโหลดไฟล์ไปยัง Amazon S3

ในขั้นแรก ให้รวมอัญมณีอีกสองเม็ดไว้ใน Gemfile :

gem "aws-sdk", "~> 2.1"group :development do gem 'dotenv-rails'end

ต้องใช้ aws-sdk เพื่อทำงานกับ SDK ของ S3 ในขณะที่ dotenv-rails จะถูกใช้เพื่อจัดการตัวแปรสภาพแวดล้อมในการพัฒนา

การติดตั้งมัด

ก่อนดำเนินการต่อ คุณควรขอรับคู่คีย์เพื่อเข้าถึง S3 ผ่าน API ในการรับข้อมูล ให้ลงชื่อเข้าใช้ (หรือลงชื่อสมัครใช้) ไปที่ Amazon Web Services Console และไปที่ข้อมูลรับรองความปลอดภัย> ผู้ใช้ . สร้างผู้ใช้ที่มีสิทธิ์จัดการไฟล์บน S3 นี่คือนโยบายง่ายๆ ที่นำเสนอการเข้าถึง S3 อย่างเต็มรูปแบบ:

{ "เวอร์ชัน":"2016-11-14", "คำสั่ง":[ { "ผล":"อนุญาต", "การดำเนินการ":"s3:*", "ทรัพยากร":"*" } ]} 

ดาวน์โหลดคู่คีย์ของผู้ใช้ที่สร้างขึ้น หรือคุณอาจใช้คีย์การเข้าถึงรูท แต่ฉัน ไม่แนะนำอย่างยิ่ง คุณจากการทำเช่นนั้นเพราะมันไม่ปลอดภัยมาก

ถัดไป สร้างบัคเก็ต S3 เพื่อโฮสต์ไฟล์ของคุณและเพิ่มไฟล์ลงในรูทของโปรเจ็กต์เพื่อโฮสต์การกำหนดค่าของคุณ:

.env

S3_KEY=YOUR_KEYS3_SECRET=YOUR_SECRETS3_BUCKET=YOUR_BUCKETS3_REGION=YOUR_REGION

ไม่เคยเปิดเผย ไฟล์นี้ต่อสาธารณะ และอย่าลืมยกเว้นจาก Git:

.gitignore

.env

ตอนนี้แก้ไขการกำหนดค่าส่วนกลางของ Shrine และแนะนำที่เก็บข้อมูลใหม่:

config/initializers/shrine.rb

require "shrine"require "shrine/storage/s3"s3_options ={ access_key_id:ENV['S3_KEY'], secret_access_key:ENV['S3_SECRET'], ภูมิภาค:ENV['S3_REGION'], ที่เก็บข้อมูล:ENV[' S3_BUCKET'],}Shrine.storages ={ แคช:Shrine::Storage::FileSystem.new("public" คำนำหน้า:"uploads/cache") ร้านค้า:Shrine::Storage::S3.new(prefix:" เก็บ", **s3_options),}

แค่นั้นแหละ! ไม่ต้องทำการเปลี่ยนแปลงในส่วนอื่นๆ ของแอป และคุณสามารถทดสอบที่เก็บข้อมูลใหม่นี้ได้ทันที หากคุณได้รับข้อผิดพลาดจาก S3 ที่เกี่ยวข้องกับคีย์ที่ไม่ถูกต้อง ตรวจสอบให้แน่ใจว่าคุณได้คัดลอกคีย์และข้อมูลลับอย่างถูกต้อง โดยไม่มีช่องว่างต่อท้ายและสัญลักษณ์พิเศษที่มองไม่เห็น

บทสรุป

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

ดังนั้น ให้เรียกดูเอกสารประกอบของ Shrine และเว็บไซต์อย่างเป็นทางการ ซึ่งอธิบายปลั๊กอินที่มีอยู่ทั้งหมดอย่างละเอียด หากคุณมีคำถามอื่นๆ เกี่ยวกับอัญมณีชิ้นนี้ อย่าลังเลที่จะโพสต์ไว้ ฉันขอขอบคุณที่อยู่กับฉัน แล้วพบกันใหม่!