Yêu cầu-html cookie

Bộ điều khiển hành động là C trong MVC. Sau khi bộ định tuyến đã xác định bộ điều khiển nào sẽ sử dụng cho yêu cầu, bộ điều khiển chịu trách nhiệm hiểu ý nghĩa của yêu cầu và tạo đầu ra phù hợp. May mắn thay, Trình điều khiển hành động thực hiện hầu hết các công việc cơ bản cho bạn và sử dụng các quy ước thông minh để làm cho điều này trở nên đơn giản nhất có thể

Đối với hầu hết các ứng dụng RESTful thông thường, bộ điều khiển sẽ nhận yêu cầu (điều này vô hình đối với bạn với tư cách là nhà phát triển), tìm nạp hoặc lưu dữ liệu từ một mô hình và sử dụng chế độ xem để tạo đầu ra HTML. Nếu bộ điều khiển của bạn cần thực hiện mọi thứ hơi khác một chút, thì đó không phải là vấn đề, đây chỉ là cách phổ biến nhất để bộ điều khiển hoạt động

Do đó, một bộ điều khiển có thể được coi là người trung gian giữa các mô hình và chế độ xem. Nó cung cấp dữ liệu mô hình cho chế độ xem, do đó, nó có thể hiển thị dữ liệu đó cho người dùng và nó lưu hoặc cập nhật dữ liệu người dùng vào mô hình

Quy ước đặt tên của bộ điều khiển trong Rails ưu tiên số nhiều của từ cuối cùng trong tên của bộ điều khiển, mặc dù nó không bắt buộc (e. g.

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
9). Ví dụ:
{ "name": "acme", "address": "123 Carrot Street" }
0 thích hợp hơn
{ "name": "acme", "address": "123 Carrot Street" }
1,
{ "name": "acme", "address": "123 Carrot Street" }
2 thích hợp hơn
{ "name": "acme", "address": "123 Carrot Street" }
3 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
4, v.v.

Tuân theo quy ước này sẽ cho phép bạn sử dụng các trình tạo tuyến đường mặc định (e. g.

{ "name": "acme", "address": "123 Carrot Street" }
5, v.v.) mà không cần phải đủ điều kiện cho mỗi
{ "name": "acme", "address": "123 Carrot Street" }
6 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
7 và sẽ duy trì việc sử dụng các trình trợ giúp định tuyến được đặt tên nhất quán trong suốt ứng dụng của bạn. Xem Bố cục và Hướng dẫn kết xuất để biết thêm chi tiết

Quy ước đặt tên của bộ điều khiển khác với quy ước đặt tên của các mô hình, dự kiến ​​sẽ được đặt tên ở dạng số ít

Bộ điều khiển là một lớp Ruby kế thừa từ

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
9 và có các phương thức giống như bất kỳ lớp nào khác. Khi ứng dụng của bạn nhận được yêu cầu, định tuyến sẽ xác định bộ điều khiển và hành động nào sẽ chạy, sau đó Rails tạo một phiên bản của bộ điều khiển đó và chạy phương thức có cùng tên với hành động

{ "name": "acme", "address": "123 Carrot Street" }
0Bản sao

Ví dụ: nếu người dùng truy cập

{ "name": "acme", "address": "123 Carrot Street" }
9 trong ứng dụng của bạn để thêm ứng dụng khách mới, Rails sẽ tạo một phiên bản của
{ "name": "acme", "address": "123 Carrot Street" }
0 và gọi phương thức
{ "name": "acme", "address": "123 Carrot Street" }
31 của nó. Lưu ý rằng phương thức trống từ ví dụ trên sẽ hoạt động tốt vì theo mặc định, Rails sẽ hiển thị chế độ xem
{ "name": "acme", "address": "123 Carrot Street" }
32 trừ khi hành động nói khác. Bằng cách tạo một
{ "name": "acme", "address": "123 Carrot Street" }
33 mới, phương thức
{ "name": "acme", "address": "123 Carrot Street" }
31 có thể làm cho biến đối tượng
{ "name": "acme", "address": "123 Carrot Street" }
35 có thể truy cập được trong dạng xem

{ "name": "acme", "address": "123 Carrot Street" }
8Bản sao

Hướng dẫn bố cục và kết xuất giải thích điều này chi tiết hơn

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
9 kế thừa từ
{ "name": "acme", "address": "123 Carrot Street" }
37, định nghĩa một số phương thức hữu ích. Hướng dẫn này sẽ đề cập đến một số trong số này, nhưng nếu bạn tò mò muốn xem có gì trong đó, bạn có thể xem tất cả chúng trong tài liệu API hoặc trong chính nguồn đó

Chỉ các phương thức công khai mới có thể gọi là hành động. Cách tốt nhất là giảm khả năng hiển thị của các phương pháp (với

{ "name": "acme", "address": "123 Carrot Street" }
38 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
39) không nhằm mục đích hành động, như phương pháp phụ trợ hoặc bộ lọc

Một số tên phương thức được dành riêng bởi Bộ điều khiển hành động. Việc vô tình xác định lại chúng dưới dạng hành động hoặc thậm chí là phương pháp phụ trợ có thể dẫn đến ____230. Nếu bạn giới hạn bộ điều khiển của mình chỉ với các hành động Định tuyến tài nguyên RESTful, bạn không cần phải lo lắng về điều này

Nếu bạn phải sử dụng một phương thức dành riêng làm tên hành động, một giải pháp thay thế là sử dụng tuyến tùy chỉnh để ánh xạ tên phương thức dành riêng cho phương thức hành động không dành riêng của bạn

Bạn có thể sẽ muốn truy cập dữ liệu do người dùng gửi hoặc các tham số khác trong hành động của bộ điều khiển của bạn. Có hai loại tham số có thể có trong một ứng dụng web. Đầu tiên là các tham số được gửi như một phần của URL, được gọi là tham số chuỗi truy vấn. Chuỗi truy vấn là mọi thứ sau "?" . Loại tham số thứ hai thường được gọi là dữ liệu POST. Thông tin này thường đến từ một biểu mẫu HTML đã được người dùng điền vào. Nó được gọi là dữ liệu POST vì nó chỉ có thể được gửi như một phần của yêu cầu HTTP POST. Rails không phân biệt giữa tham số chuỗi truy vấn và tham số POST và cả hai đều có sẵn trong hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
31 trong bộ điều khiển của bạn

{ "name": "acme", "address": "123 Carrot Street" }
5Bản sao

4. 1 Tham số băm và mảng

Hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
31 không giới hạn ở các khóa và giá trị một chiều. Nó có thể chứa các mảng và giá trị băm lồng nhau. Để gửi một mảng giá trị, hãy thêm một cặp dấu ngoặc vuông trống "[]" vào tên khóa

{ "name": "acme", "address": "123 Carrot Street" }
7Bản sao

URL thực tế trong ví dụ này sẽ được mã hóa thành "/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3" vì các ký tự "[" và "]" không được phép trong URL. Hầu hết thời gian bạn không phải lo lắng về điều này vì trình duyệt sẽ mã hóa nó cho bạn và Rails sẽ tự động giải mã nó, nhưng nếu bạn thấy mình phải gửi các yêu cầu đó đến máy chủ theo cách thủ công thì bạn nên ghi nhớ điều này

Giá trị của

{ "name": "acme", "address": "123 Carrot Street" }
33 bây giờ sẽ là
{ "name": "acme", "address": "123 Carrot Street" }
34. Lưu ý rằng giá trị tham số luôn là chuỗi;

Theo mặc định, các giá trị như

{ "name": "acme", "address": "123 Carrot Street" }
35 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
36 trong
{ "name": "acme", "address": "123 Carrot Street" }
31 được thay thế bằng
{ "name": "acme", "address": "123 Carrot Street" }
38 vì lý do bảo mật. Xem Hướng dẫn bảo mật để biết thêm thông tin

Để gửi hàm băm, bạn nhập tên khóa bên trong dấu ngoặc

{ "name": "acme", "address": "123 Carrot Street" }
4Bản sao

Khi biểu mẫu này được gửi, giá trị của

{ "name": "acme", "address": "123 Carrot Street" }
39 sẽ là
{ "name": "acme", "address": "123 Carrot Street" }
60. Lưu ý hàm băm lồng nhau trong
{ "name": "acme", "address": "123 Carrot Street" }
61

Đối tượng

{ "name": "acme", "address": "123 Carrot Street" }
31 hoạt động giống như Hash, nhưng cho phép bạn sử dụng các ký hiệu và chuỗi thay thế cho nhau làm khóa

4. 2 tham số JSON

Nếu bạn đang viết một ứng dụng dịch vụ web, bạn có thể thấy thoải mái hơn khi chấp nhận các tham số ở định dạng JSON. Nếu tiêu đề "Content-Type" trong yêu cầu của bạn được đặt thành "application/json", Rails sẽ tự động tải các tham số của bạn vào hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
31 mà bạn có thể truy cập như bình thường

Vì vậy, ví dụ: nếu bạn đang gửi nội dung JSON này

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
Bản sao

Bộ điều khiển của bạn sẽ nhận được

{ "name": "acme", "address": "123 Carrot Street" }
64 dưới dạng
{ "name": "acme", "address": "123 Carrot Street" }
65

Ngoài ra, nếu bạn đã bật

{ "name": "acme", "address": "123 Carrot Street" }
66 trong trình khởi tạo hoặc gọi là
{ "name": "acme", "address": "123 Carrot Street" }
67 trong bộ điều khiển của mình, thì bạn có thể yên tâm bỏ qua phần tử gốc trong tham số JSON. Trong trường hợp này, các tham số sẽ được sao chép và bọc bằng một khóa được chọn dựa trên tên bộ điều khiển của bạn. Vì vậy, yêu cầu JSON ở trên có thể được viết là

{ "name": "acme", "address": "123 Carrot Street" }
Bản sao

Và, giả sử rằng bạn đang gửi dữ liệu tới

{ "name": "acme", "address": "123 Carrot Street" }
68, thì dữ liệu sẽ được gói trong khóa
{ "name": "acme", "address": "123 Carrot Street" }
69 như thế này

{ "name": "acme", "address": "123 Carrot Street" }
3Bản sao

Bạn có thể tùy chỉnh tên của khóa hoặc tham số cụ thể mà bạn muốn ngắt bằng cách tham khảo tài liệu API

Hỗ trợ phân tích các tham số XML đã được trích xuất thành một viên ngọc có tên là

{ "name": "acme", "address": "123 Carrot Street" }
800

4. 3 Tham số định tuyến

Băm

{ "name": "acme", "address": "123 Carrot Street" }
31 sẽ luôn chứa các khóa
{ "name": "acme", "address": "123 Carrot Street" }
7 và
{ "name": "acme", "address": "123 Carrot Street" }
803, nhưng bạn nên sử dụng các phương thức
{ "name": "acme", "address": "123 Carrot Street" }
804 và
{ "name": "acme", "address": "123 Carrot Street" }
805 thay vì truy cập các giá trị này. Bất kỳ tham số nào khác được xác định bởi định tuyến, chẳng hạn như
{ "name": "acme", "address": "123 Carrot Street" }
806, cũng sẽ khả dụng. Ví dụ: xem xét danh sách khách hàng trong đó danh sách có thể hiển thị khách hàng đang hoạt động hoặc không hoạt động. Chúng tôi có thể thêm một tuyến đường nắm bắt tham số
{ "name": "acme", "address": "123 Carrot Street" }
807 trong một URL "đẹp"

{ "name": "acme", "address": "123 Carrot Street" }
3Bản sao

Trong trường hợp này, khi người dùng mở URL

{ "name": "acme", "address": "123 Carrot Street" }
808, thì
{ "name": "acme", "address": "123 Carrot Street" }
809 sẽ được đặt thành "hoạt động". Khi tuyến đường này được sử dụng,
{ "name": "acme", "address": "123 Carrot Street" }
810 cũng sẽ được đặt thành "bar", như thể nó được chuyển vào chuỗi truy vấn. Bộ điều khiển của bạn cũng sẽ nhận được
{ "name": "acme", "address": "123 Carrot Street" }
811 là "chỉ mục" và
{ "name": "acme", "address": "123 Carrot Street" }
812 là "máy khách"

4. 4
{ "name": "acme", "address": "123 Carrot Street" }
813

Bạn có thể đặt các tham số mặc định chung để tạo URL bằng cách xác định một phương thức có tên là

{ "name": "acme", "address": "123 Carrot Street" }
813 trong bộ điều khiển của mình. Một phương thức như vậy phải trả về một hàm băm với các giá trị mặc định mong muốn, các khóa của chúng phải là các ký hiệu

{ "name": "acme", "address": "123 Carrot Street" }
6Bản sao

Các tùy chọn này sẽ được sử dụng làm điểm bắt đầu khi tạo URL, vì vậy có thể chúng sẽ bị ghi đè bởi các tùy chọn được chuyển đến cuộc gọi

{ "name": "acme", "address": "123 Carrot Street" }
815

Nếu bạn xác định

{ "name": "acme", "address": "123 Carrot Street" }
813 trong
{ "company": { "name": "acme", "address": "123 Carrot Street" } }
9, như trong ví dụ trên, các giá trị mặc định này sẽ được sử dụng cho tất cả việc tạo URL. Phương thức này cũng có thể được xác định trong một bộ điều khiển cụ thể, trong trường hợp đó, nó chỉ ảnh hưởng đến các URL được tạo ở đó

Trong một yêu cầu nhất định, phương thức này không thực sự được gọi cho mọi URL được tạo. Vì lý do hiệu suất, hàm băm trả về được lưu vào bộ đệm và có tối đa một lệnh gọi cho mỗi yêu cầu

4. 5 thông số mạnh mẽ

Với các tham số mạnh, các tham số của Bộ điều khiển Hành động bị cấm sử dụng trong các phép gán khối lượng của Mô hình Hoạt động cho đến khi chúng được cho phép. Điều này có nghĩa là bạn sẽ phải đưa ra quyết định sáng suốt về những thuộc tính nào sẽ cho phép cập nhật hàng loạt. Đây là một phương pháp bảo mật tốt hơn để giúp ngăn việc vô tình cho phép người dùng cập nhật các thuộc tính mô hình nhạy cảm

Ngoài ra, các tham số có thể được đánh dấu là bắt buộc và sẽ chảy qua luồng tăng/cứu được xác định trước, điều này sẽ dẫn đến 400 Yêu cầu không hợp lệ được trả về nếu không phải tất cả các tham số bắt buộc đều được chuyển vào

{ "name": "acme", "address": "123 Carrot Street" }
80Bản sao

4. 5. 1 giá trị vô hướng được phép

Đang gọi

{ "name": "acme", "address": "123 Carrot Street" }
818 thích

cho phép khóa được chỉ định (

{ "name": "acme", "address": "123 Carrot Street" }
806) được đưa vào nếu nó xuất hiện trong
{ "name": "acme", "address": "123 Carrot Street" }
31 và nó có giá trị vô hướng được phép liên quan. Nếu không, khóa sẽ bị lọc ra, do đó, mảng, giá trị băm hoặc bất kỳ đối tượng nào khác không thể được đưa vào

Các loại vô hướng được phép là

{ "name": "acme", "address": "123 Carrot Street" }
821,
{ "name": "acme", "address": "123 Carrot Street" }
822,
{ "name": "acme", "address": "123 Carrot Street" }
823,
{ "name": "acme", "address": "123 Carrot Street" }
824,
{ "name": "acme", "address": "123 Carrot Street" }
825,
{ "name": "acme", "address": "123 Carrot Street" }
826,
{ "name": "acme", "address": "123 Carrot Street" }
827,
{ "name": "acme", "address": "123 Carrot Street" }
828,
{ "name": "acme", "address": "123 Carrot Street" }
829,
{ "name": "acme", "address": "123 Carrot Street" }
830,
{ "name": "acme", "address": "123 Carrot Street" }
831,
{ "name": "acme", "address": "123 Carrot Street" }
832, và
{ "name": "acme", "address": "123 Carrot Street" }
833

Để khai báo rằng giá trị trong

{ "name": "acme", "address": "123 Carrot Street" }
31 phải là một mảng các giá trị vô hướng được phép, hãy ánh xạ khóa tới một mảng trống

Đôi khi không thể hoặc không thuận tiện để khai báo các khóa hợp lệ của tham số băm hoặc cấu trúc bên trong của nó. Chỉ cần ánh xạ tới một hàm băm trống

{ "name": "acme", "address": "123 Carrot Street" }
81Bản sao

nhưng hãy cẩn thận vì điều này mở ra cơ hội cho đầu vào tùy ý. Trong trường hợp này,

{ "name": "acme", "address": "123 Carrot Street" }
818 đảm bảo các giá trị trong cấu trúc được trả về là các giá trị vô hướng được phép và lọc ra bất kỳ thứ gì khác

Để cho phép toàn bộ hàm băm tham số, phương thức

{ "name": "acme", "address": "123 Carrot Street" }
836 có thể được sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
82Bản sao

Điều này đánh dấu hàm băm tham số

{ "name": "acme", "address": "123 Carrot Street" }
837 và bất kỳ hàm băm phụ nào của nó là được phép và không kiểm tra các đại lượng vô hướng được phép, mọi thứ đều được chấp nhận. Cần hết sức cẩn thận khi sử dụng
{ "name": "acme", "address": "123 Carrot Street" }
836, vì nó sẽ cho phép tất cả các thuộc tính mô hình hiện tại và tương lai được gán hàng loạt

4. 5. 2 tham số lồng nhau

Bạn cũng có thể sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
818 trên các tham số lồng nhau, chẳng hạn như

{ "name": "acme", "address": "123 Carrot Street" }
83Bản sao

Tuyên bố này cho phép các thuộc tính

{ "name": "acme", "address": "123 Carrot Street" }
840,
{ "name": "acme", "address": "123 Carrot Street" }
841 và
{ "name": "acme", "address": "123 Carrot Street" }
842. Dự kiến,
{ "name": "acme", "address": "123 Carrot Street" }
841 sẽ là một mảng các giá trị vô hướng được phép và
{ "name": "acme", "address": "123 Carrot Street" }
842 sẽ là một mảng tài nguyên với các thuộc tính cụ thể. chúng phải có thuộc tính
{ "name": "acme", "address": "123 Carrot Street" }
840 (cho phép mọi giá trị vô hướng được phép), thuộc tính
{ "name": "acme", "address": "123 Carrot Street" }
846 dưới dạng một mảng các giá trị vô hướng được phép và thuộc tính
{ "name": "acme", "address": "123 Carrot Street" }
847 bị hạn chế ở mức có ____1840 (bất kỳ giá trị vô hướng được phép nào cũng được phép ở đây)

4. 5. 3 ví dụ khác

Bạn cũng có thể muốn sử dụng các thuộc tính được phép trong hành động

{ "name": "acme", "address": "123 Carrot Street" }
31 của mình. Điều này đặt ra vấn đề là bạn không thể sử dụng
{ "name": "acme", "address": "123 Carrot Street" }
850 trên khóa gốc vì thông thường, nó không tồn tại khi gọi
{ "name": "acme", "address": "123 Carrot Street" }
31

{ "name": "acme", "address": "123 Carrot Street" }
84Bản sao

Phương thức lớp mô hình

{ "name": "acme", "address": "123 Carrot Street" }
852 cho phép bạn cập nhật và hủy các bản ghi liên quan. Điều này dựa trên các tham số
{ "name": "acme", "address": "123 Carrot Street" }
853 và
{ "name": "acme", "address": "123 Carrot Street" }
854

{ "name": "acme", "address": "123 Carrot Street" }
85Bản sao

Băm với các khóa số nguyên được xử lý khác nhau và bạn có thể khai báo các thuộc tính như thể chúng là con trực tiếp. Bạn nhận được các loại tham số này khi sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
852 kết hợp với liên kết
{ "name": "acme", "address": "123 Carrot Street" }
856

{ "name": "acme", "address": "123 Carrot Street" }
86Bản sao

Hãy tưởng tượng một kịch bản trong đó bạn có các tham số đại diện cho tên sản phẩm và hàm băm dữ liệu tùy ý được liên kết với sản phẩm đó và bạn muốn cho phép thuộc tính tên sản phẩm cũng như toàn bộ dữ liệu băm

{ "name": "acme", "address": "123 Carrot Street" }
87Bản sao

4. 5. 4 Bên ngoài phạm vi của các thông số mạnh

API tham số mạnh được thiết kế có tính đến các trường hợp sử dụng phổ biến nhất. Nó không phải là viên đạn bạc để xử lý tất cả các vấn đề về lọc thông số của bạn. Tuy nhiên, bạn có thể dễ dàng kết hợp API với mã của riêng mình để thích ứng với tình huống của mình

Ứng dụng của bạn có một phiên cho mỗi người dùng, trong đó bạn có thể lưu trữ một lượng nhỏ dữ liệu sẽ được duy trì giữa các yêu cầu. Phiên chỉ khả dụng trong bộ điều khiển và chế độ xem và có thể sử dụng một trong số các cơ chế lưu trữ khác nhau

Tất cả các cửa hàng phiên sử dụng cookie để lưu ID duy nhất cho mỗi phiên (bạn phải sử dụng cookie, Rails sẽ không cho phép bạn chuyển ID phiên vào URL vì điều này kém an toàn hơn)

Đối với hầu hết các cửa hàng, ID này được sử dụng để tra cứu dữ liệu phiên trên máy chủ, e. g. trong một bảng cơ sở dữ liệu. Có một ngoại lệ, đó là kho lưu trữ phiên mặc định và được đề xuất - CookieStore - nơi lưu trữ tất cả dữ liệu phiên trong chính cookie (ID vẫn có sẵn cho bạn nếu bạn cần). Điều này có ưu điểm là rất nhẹ và không yêu cầu thiết lập trong một ứng dụng mới để sử dụng phiên. Dữ liệu cookie được ký bằng mật mã để chống giả mạo. Và nó cũng được mã hóa để bất kỳ ai có quyền truy cập vào nó đều không thể đọc được nội dung của nó. (Rails sẽ không chấp nhận nếu nó đã được chỉnh sửa)

CookieStore có thể lưu trữ khoảng 4 kB dữ liệu - ít hơn nhiều so với các loại khác - nhưng điều này thường là đủ. Việc lưu trữ một lượng lớn dữ liệu trong phiên không được khuyến khích cho dù ứng dụng của bạn sử dụng lưu trữ phiên nào. Bạn đặc biệt nên tránh lưu trữ các đối tượng phức tạp (chẳng hạn như phiên bản mô hình) trong phiên, vì máy chủ có thể không lắp ráp lại chúng giữa các yêu cầu, điều này sẽ dẫn đến lỗi

Nếu phiên người dùng của bạn không lưu trữ dữ liệu quan trọng hoặc không cần tồn tại trong thời gian dài (ví dụ: nếu bạn chỉ sử dụng đèn flash để nhắn tin), bạn có thể cân nhắc sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
857. Điều này sẽ lưu trữ các phiên bằng cách sử dụng triển khai bộ đệm mà bạn đã định cấu hình cho ứng dụng của mình. Ưu điểm của điều này là bạn có thể sử dụng cơ sở hạ tầng bộ đệm hiện tại của mình để lưu trữ các phiên mà không yêu cầu bất kỳ thiết lập hoặc quản trị bổ sung nào. Tất nhiên, nhược điểm là các phiên sẽ không lâu và có thể biến mất bất cứ lúc nào.

Đọc thêm về lưu trữ phiên trong Hướng dẫn bảo mật

Nếu bạn cần một cơ chế lưu trữ phiên khác, bạn có thể thay đổi nó trong trình khởi tạo

{ "name": "acme", "address": "123 Carrot Street" }
88Bản sao

Rails thiết lập khóa phiên (tên của cookie) khi ký dữ liệu phiên. Chúng cũng có thể được thay đổi trong trình khởi tạo

{ "name": "acme", "address": "123 Carrot Street" }
89Bản sao

Bạn cũng có thể chuyển khóa

{ "name": "acme", "address": "123 Carrot Street" }
858 và chỉ định tên miền cho cookie

{ "name": "acme", "address": "123 Carrot Street" }
50Bản sao

Rails thiết lập (cho CookieStore) một khóa bí mật được sử dụng để ký dữ liệu phiên trong

{ "name": "acme", "address": "123 Carrot Street" }
859. Điều này có thể được thay đổi với
{ "name": "acme", "address": "123 Carrot Street" }
860

{ "name": "acme", "address": "123 Carrot Street" }
51Bản sao

Thay đổi secret_key_base khi sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
861 sẽ làm mất hiệu lực tất cả các phiên hiện có

5. 1 Truy cập phiên

Trong bộ điều khiển của bạn, bạn có thể truy cập phiên thông qua phương thức đối tượng

{ "name": "acme", "address": "123 Carrot Street" }
862

Các phiên được tải một cách lười biếng. Nếu bạn không truy cập các phiên trong mã hành động của mình, chúng sẽ không được tải. Do đó, bạn sẽ không bao giờ cần phải tắt các phiên, chỉ cần không truy cập chúng sẽ thực hiện công việc

Các giá trị phiên được lưu trữ bằng cách sử dụng các cặp khóa/giá trị giống như hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
52Bản sao

Để lưu trữ thứ gì đó trong phiên, chỉ cần gán nó cho khóa như hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
53Bản sao

Để xóa thứ gì đó khỏi phiên, hãy xóa cặp khóa/giá trị

{ "name": "acme", "address": "123 Carrot Street" }
54Bản sao

Để đặt lại toàn bộ phiên, hãy sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
863

5. 2 Tia Chớp

Đèn flash là một phần đặc biệt của phiên sẽ bị xóa với mỗi yêu cầu. Điều này có nghĩa là các giá trị được lưu trữ ở đó sẽ chỉ khả dụng trong yêu cầu tiếp theo, điều này hữu ích cho việc chuyển thông báo lỗi, v.v.

Đèn flash được truy cập thông qua phương pháp

{ "name": "acme", "address": "123 Carrot Street" }
864. Giống như phiên, đèn flash được biểu thị dưới dạng hàm băm

Hãy sử dụng hành động đăng xuất làm ví dụ. Bộ điều khiển có thể gửi một tin nhắn sẽ được hiển thị cho người dùng trong yêu cầu tiếp theo

{ "name": "acme", "address": "123 Carrot Street" }
55Bản sao

Lưu ý rằng cũng có thể chỉ định một tin nhắn flash như một phần của chuyển hướng. Bạn có thể chỉ định

{ "name": "acme", "address": "123 Carrot Street" }
865,
{ "name": "acme", "address": "123 Carrot Street" }
866 hoặc mục đích chung
{ "name": "acme", "address": "123 Carrot Street" }
867

{ "name": "acme", "address": "123 Carrot Street" }
56Bản sao

Hành động ________ 1868 chuyển hướng đến ________ 1869 của ứng dụng, nơi thông báo sẽ được hiển thị. Lưu ý rằng hành động tiếp theo sẽ quyết định điều gì, nếu có, sẽ làm gì với hành động trước đó đưa vào flash hoàn toàn phụ thuộc vào hành động tiếp theo. Thông thường sẽ hiển thị bất kỳ cảnh báo lỗi hoặc thông báo nào từ đèn flash trong bố cục của ứng dụng

{ "name": "acme", "address": "123 Carrot Street" }
57Bản sao

Bằng cách này, nếu một hành động đặt thông báo hoặc thông báo cảnh báo, bố cục sẽ tự động hiển thị thông báo đó

Bạn có thể chuyển bất kỳ thứ gì mà phiên có thể lưu trữ;

{ "name": "acme", "address": "123 Carrot Street" }
58Bản sao

Nếu bạn muốn một giá trị flash được chuyển sang yêu cầu khác, hãy sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
870

{ "name": "acme", "address": "123 Carrot Street" }
59Bản sao

5. 2. 1
{ "name": "acme", "address": "123 Carrot Street" }
871

Theo mặc định, việc thêm các giá trị vào flash sẽ cung cấp các giá trị đó cho yêu cầu tiếp theo, nhưng đôi khi bạn có thể muốn truy cập các giá trị đó trong cùng một yêu cầu. Ví dụ: nếu hành động

{ "name": "acme", "address": "123 Carrot Street" }
872 không lưu được tài nguyên và bạn hiển thị trực tiếp mẫu
{ "name": "acme", "address": "123 Carrot Street" }
31, điều đó sẽ không dẫn đến yêu cầu mới, nhưng bạn vẫn có thể muốn hiển thị thông báo bằng flash. Để làm điều này, bạn có thể sử dụng
{ "name": "acme", "address": "123 Carrot Street" }
871 giống như cách bạn sử dụng
{ "name": "acme", "address": "123 Carrot Street" }
864 bình thường

{ "name": "acme", "address": "123 Carrot Street" }
70Bản sao

Ứng dụng của bạn có thể lưu trữ một lượng nhỏ dữ liệu trên máy khách - được gọi là cookie - sẽ được duy trì trong các yêu cầu và thậm chí cả phiên. Rails cung cấp quyền truy cập dễ dàng vào cookie thông qua phương thức

{ "name": "acme", "address": "123 Carrot Street" }
876, phương thức này - giống như phương thức
{ "name": "acme", "address": "123 Carrot Street" }
862 - hoạt động giống như hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
71Bản sao

Lưu ý rằng trong khi đối với giá trị phiên, bạn có thể đặt khóa thành

{ "name": "acme", "address": "123 Carrot Street" }
878, để xóa giá trị cookie, bạn nên sử dụng
{ "name": "acme", "address": "123 Carrot Street" }
879

Rails cũng cung cấp một lọ cookie đã ký và một lọ cookie được mã hóa để lưu trữ dữ liệu nhạy cảm. Lọ cookie đã ký sẽ thêm chữ ký mã hóa vào các giá trị cookie để bảo vệ tính toàn vẹn của chúng. Lọ cookie được mã hóa mã hóa các giá trị ngoài việc ký chúng để người dùng cuối không thể đọc được chúng. Tham khảo tài liệu API để biết thêm chi tiết

Các lọ cookie đặc biệt này sử dụng bộ tuần tự hóa để tuần tự hóa các giá trị được gán thành các chuỗi và giải tuần tự hóa chúng thành các đối tượng Ruby khi đọc

Bạn có thể chỉ định bộ nối tiếp nào sẽ sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
72Bản sao

Bộ nối tiếp mặc định cho các ứng dụng mới là

{ "name": "acme", "address": "123 Carrot Street" }
880. Để tương thích với các ứng dụng cũ có cookie hiện có,
{ "name": "acme", "address": "123 Carrot Street" }
881 được sử dụng khi tùy chọn
{ "name": "acme", "address": "123 Carrot Street" }
882 không được chỉ định

Bạn cũng có thể đặt tùy chọn này thành

{ "name": "acme", "address": "123 Carrot Street" }
883, trong trường hợp đó, Rails sẽ giải tuần tự hóa các cookie hiện có (
{ "name": "acme", "address": "123 Carrot Street" }
884-serialized) hiện có khi đọc và viết lại chúng ở định dạng
{ "name": "acme", "address": "123 Carrot Street" }
885. Điều này hữu ích cho việc di chuyển các ứng dụng hiện có sang bộ tuần tự hóa
{ "name": "acme", "address": "123 Carrot Street" }
880

Cũng có thể chuyển bộ nối tiếp tùy chỉnh đáp ứng với

{ "name": "acme", "address": "123 Carrot Street" }
887 và
{ "name": "acme", "address": "123 Carrot Street" }
888

{ "name": "acme", "address": "123 Carrot Street" }
73Bản sao

Khi sử dụng trình tuần tự hóa

{ "name": "acme", "address": "123 Carrot Street" }
880 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
883, bạn nên lưu ý rằng không phải tất cả các đối tượng Ruby đều có thể được tuần tự hóa dưới dạng JSON. Ví dụ: các đối tượng
{ "name": "acme", "address": "123 Carrot Street" }
827 và
{ "name": "acme", "address": "123 Carrot Street" }
828 sẽ được đánh số thứ tự thành chuỗi và các đối tượng
{ "name": "acme", "address": "123 Carrot Street" }
893 sẽ có khóa được xâu chuỗi

{ "name": "acme", "address": "123 Carrot Street" }
74Bản sao

Bạn chỉ nên lưu trữ dữ liệu đơn giản (chuỗi và số) trong cookie. Nếu bạn phải lưu trữ các đối tượng phức tạp, bạn sẽ cần xử lý chuyển đổi theo cách thủ công khi đọc các giá trị trong các yêu cầu tiếp theo

Nếu bạn sử dụng cửa hàng phiên cookie, điều này cũng sẽ áp dụng cho hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
862 và
{ "name": "acme", "address": "123 Carrot Street" }
864

ActionController giúp kết xuất dữ liệu

{ "name": "acme", "address": "123 Carrot Street" }
896 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
885 cực kỳ dễ dàng. Nếu bạn đã tạo bộ điều khiển bằng cách sử dụng giàn giáo, nó sẽ giống như thế này

{ "name": "acme", "address": "123 Carrot Street" }
75Bản sao

Bạn có thể nhận thấy trong đoạn mã trên rằng chúng tôi đang sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
898, không phải
{ "name": "acme", "address": "123 Carrot Street" }
899. Nếu đối tượng không phải là String thì Rails sẽ tự động gọi
{ "name": "acme", "address": "123 Carrot Street" }
500 cho chúng ta

Bộ lọc là các phương thức được chạy "trước", "sau" hoặc "xung quanh" một hành động của bộ điều khiển

Các bộ lọc được kế thừa, vì vậy nếu bạn đặt bộ lọc trên

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
9, nó sẽ chạy trên mọi bộ điều khiển trong ứng dụng của bạn

bộ lọc "trước" được đăng ký qua

{ "name": "acme", "address": "123 Carrot Street" }
502. Họ có thể tạm dừng chu kỳ yêu cầu. Bộ lọc "trước" phổ biến là bộ lọc yêu cầu người dùng phải đăng nhập để thực hiện một hành động. Bạn có thể xác định phương thức lọc theo cách này

{ "name": "acme", "address": "123 Carrot Street" }
76Bản sao

Phương thức đơn giản là lưu thông báo lỗi trong flash và chuyển hướng đến biểu mẫu đăng nhập nếu người dùng chưa đăng nhập. Nếu bộ lọc "trước" hiển thị hoặc chuyển hướng, hành động sẽ không chạy. Nếu có các bộ lọc bổ sung được lên lịch để chạy sau bộ lọc đó, thì chúng cũng bị hủy

Trong ví dụ này, bộ lọc được thêm vào

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
9 và do đó, tất cả bộ điều khiển trong ứng dụng đều kế thừa bộ lọc đó. Điều này sẽ làm cho mọi thứ trong ứng dụng yêu cầu người dùng phải đăng nhập để sử dụng nó. Vì những lý do rõ ràng (người dùng sẽ không thể đăng nhập ngay từ đầu. ), không phải tất cả các bộ điều khiển hoặc hành động đều yêu cầu điều này. Bạn có thể ngăn bộ lọc này chạy trước các hành động cụ thể với
{ "name": "acme", "address": "123 Carrot Street" }
504

{ "name": "acme", "address": "123 Carrot Street" }
77Bản sao

Bây giờ, các hành động

{ "name": "acme", "address": "123 Carrot Street" }
31 và
{ "name": "acme", "address": "123 Carrot Street" }
872 của
{ "name": "acme", "address": "123 Carrot Street" }
505 sẽ hoạt động như trước mà không yêu cầu người dùng phải đăng nhập. Tùy chọn
{ "name": "acme", "address": "123 Carrot Street" }
508 chỉ được sử dụng để bỏ qua bộ lọc này cho những hành động này và cũng có tùy chọn
{ "name": "acme", "address": "123 Carrot Street" }
509 hoạt động theo cách khác. Các tùy chọn này cũng có thể được sử dụng khi thêm bộ lọc, vì vậy bạn có thể thêm bộ lọc chỉ chạy cho các hành động đã chọn ngay từ đầu

Gọi cùng một bộ lọc nhiều lần với các tùy chọn khác nhau sẽ không hoạt động, vì định nghĩa bộ lọc cuối cùng sẽ ghi đè lên các bộ lọc trước đó

8. 1 Sau bộ lọc và xung quanh bộ lọc

Ngoài các bộ lọc "trước", bạn cũng có thể chạy các bộ lọc sau khi một hành động đã được thực hiện hoặc cả trước và sau

bộ lọc "sau" được đăng ký qua

{ "name": "acme", "address": "123 Carrot Street" }
510. Chúng tương tự như bộ lọc "trước", nhưng vì hành động đã được chạy nên chúng có quyền truy cập vào dữ liệu phản hồi sắp được gửi tới máy khách. Rõ ràng, các bộ lọc "sau" không thể dừng hành động đang chạy. Xin lưu ý rằng các bộ lọc "sau" chỉ được thực thi sau một hành động thành công chứ không phải khi một ngoại lệ được đưa ra trong chu kỳ yêu cầu

bộ lọc "xung quanh" được đăng ký qua

{ "name": "acme", "address": "123 Carrot Street" }
511. Họ chịu trách nhiệm chạy các hành động liên quan của mình bằng cách tạo năng suất, tương tự như cách hoạt động của phần mềm trung gian Rack

Ví dụ: trong một trang web nơi các thay đổi có quy trình phê duyệt, quản trị viên có thể dễ dàng xem trước chúng bằng cách áp dụng chúng trong một giao dịch

{ "name": "acme", "address": "123 Carrot Street" }
78Bản sao

Lưu ý rằng bộ lọc "xung quanh" cũng kết thúc kết xuất. Đặc biệt, trong ví dụ trên, nếu bản thân chế độ xem đọc từ cơ sở dữ liệu (e. g. thông qua một phạm vi), nó sẽ làm như vậy trong giao dịch và do đó trình bày dữ liệu để xem trước

Bạn có thể chọn không nhượng bộ và tự xây dựng phản hồi, trong trường hợp đó, hành động sẽ không được thực hiện

8. 2 cách khác để sử dụng bộ lọc

Mặc dù cách phổ biến nhất để sử dụng bộ lọc là tạo các phương thức riêng tư và sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
502,
{ "name": "acme", "address": "123 Carrot Street" }
510 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
511 để thêm chúng, nhưng có hai cách khác để thực hiện điều tương tự

Đầu tiên là sử dụng một khối trực tiếp với các phương pháp

{ "name": "acme", "address": "123 Carrot Street" }
515. Khối nhận bộ điều khiển làm đối số. Bộ lọc
{ "name": "acme", "address": "123 Carrot Street" }
516 ở trên có thể được viết lại để sử dụng một khối

{ "name": "acme", "address": "123 Carrot Street" }
79Bản sao

Lưu ý rằng bộ lọc, trong trường hợp này, sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
517 vì phương thức
{ "name": "acme", "address": "123 Carrot Street" }
518 là riêng tư và bộ lọc không chạy trong phạm vi của bộ điều khiển. Đây không phải là cách được đề xuất để thực hiện bộ lọc cụ thể này, nhưng trong những trường hợp đơn giản hơn, nó có thể hữu ích

Cụ thể đối với

{ "name": "acme", "address": "123 Carrot Street" }
511, khối này cũng mang lại trong
{ "name": "acme", "address": "123 Carrot Street" }
520

{ "name": "acme", "address": "123 Carrot Street" }
40Bản sao

Cách thứ hai là sử dụng một lớp (thực ra bất kỳ đối tượng nào đáp ứng đúng phương thức sẽ làm) để xử lý việc lọc. Điều này hữu ích trong các trường hợp phức tạp hơn và không thể triển khai theo cách có thể đọc và sử dụng lại được bằng hai phương pháp khác. Ví dụ, bạn có thể viết lại bộ lọc đăng nhập để sử dụng một lớp

{ "name": "acme", "address": "123 Carrot Street" }
41Bản sao

Một lần nữa, đây không phải là một ví dụ lý tưởng cho bộ lọc này, bởi vì nó không chạy trong phạm vi của bộ điều khiển mà được bộ điều khiển chuyển qua làm đối số. Lớp bộ lọc phải triển khai phương thức có cùng tên với bộ lọc, vì vậy đối với bộ lọc

{ "name": "acme", "address": "123 Carrot Street" }
502, lớp phải triển khai phương thức
{ "name": "acme", "address": "123 Carrot Street" }
522, v.v. Phương thức
{ "name": "acme", "address": "123 Carrot Street" }
523 ​​phải
{ "name": "acme", "address": "123 Carrot Street" }
524 để thực hiện hành động

Giả mạo yêu cầu trên nhiều trang web là một kiểu tấn công trong đó một trang web lừa người dùng thực hiện các yêu cầu trên một trang web khác, có thể thêm, sửa đổi hoặc xóa dữ liệu trên trang web đó mà người dùng không biết hoặc không được phép

Bước đầu tiên để tránh điều này là đảm bảo tất cả các hành động "phá hoại" (tạo, cập nhật và hủy) chỉ có thể được truy cập bằng các yêu cầu không NHẬN. Nếu bạn đang tuân theo các quy ước RESTful, bạn đã thực hiện việc này. Tuy nhiên, một trang web độc hại vẫn có thể gửi yêu cầu KHÔNG NHẬN đến trang web của bạn khá dễ dàng và đó là lúc yêu cầu bảo vệ giả mạo xuất hiện. Đúng như tên gọi, nó bảo vệ khỏi các yêu cầu giả mạo

Cách này được thực hiện là thêm mã thông báo không thể đoán được mà chỉ máy chủ của bạn biết cho mỗi yêu cầu. Bằng cách này, nếu một yêu cầu đến mà không có mã thông báo phù hợp, nó sẽ bị từ chối truy cập

Nếu bạn tạo một biểu mẫu như thế này

{ "name": "acme", "address": "123 Carrot Street" }
42Bản sao

Bạn sẽ thấy cách mã thông báo được thêm dưới dạng trường ẩn

{ "name": "acme", "address": "123 Carrot Street" }
43Bản sao

Rails thêm mã thông báo này vào mọi biểu mẫu được tạo bằng trình trợ giúp biểu mẫu, vì vậy hầu hết thời gian bạn không phải lo lắng về điều đó. Nếu bạn đang viết biểu mẫu theo cách thủ công hoặc cần thêm mã thông báo vì lý do khác, thì có sẵn thông qua phương pháp

{ "name": "acme", "address": "123 Carrot Street" }
525

{ "name": "acme", "address": "123 Carrot Street" }
525 tạo mã thông báo xác thực hợp lệ. Điều đó hữu ích ở những nơi mà Rails không tự động thêm nó, chẳng hạn như trong các cuộc gọi Ajax tùy chỉnh

Hướng dẫn bảo mật có nhiều hơn về vấn đề này và rất nhiều vấn đề liên quan đến bảo mật khác mà bạn nên biết khi phát triển ứng dụng web

Trong mọi bộ điều khiển, có hai phương thức truy cập trỏ đến các đối tượng yêu cầu và phản hồi được liên kết với chu kỳ yêu cầu hiện đang được thực thi. Phương thức

{ "name": "acme", "address": "123 Carrot Street" }
527 chứa một thể hiện của
{ "name": "acme", "address": "123 Carrot Street" }
528 và phương thức
{ "name": "acme", "address": "123 Carrot Street" }
529 trả về một đối tượng phản hồi đại diện cho những gì sẽ được gửi lại cho máy khách

10. 1 Đối tượng
{ "name": "acme", "address": "123 Carrot Street" }
527

Đối tượng yêu cầu chứa nhiều thông tin hữu ích về yêu cầu đến từ máy khách. Để có danh sách đầy đủ các phương thức có sẵn, hãy tham khảo tài liệu Rails API và Tài liệu Rack. Trong số các thuộc tính mà bạn có thể truy cập trên đối tượng này là

Tài sản của
{ "name": "acme", "address": "123 Carrot Street" }
527Mục đích
{ "name": "acme", "address": "123 Carrot Street" }
532Tên máy chủ được sử dụng cho yêu cầu này.
{ "name": "acme", "address": "123 Carrot Street" }
533Phân đoạn
{ "name": "acme", "address": "123 Carrot Street" }
534 đầu tiên của tên máy chủ, bắt đầu từ bên phải (TLD).
{ "name": "acme", "address": "123 Carrot Street" }
535Loại nội dung do khách hàng yêu cầu.
{ "name": "acme", "address": "123 Carrot Street" }
536Phương thức HTTP được sử dụng cho yêu cầu.
{ "name": "acme", "address": "123 Carrot Street" }
537,
{ "name": "acme", "address": "123 Carrot Street" }
538,
{ "name": "acme", "address": "123 Carrot Street" }
539,
{ "name": "acme", "address": "123 Carrot Street" }
540,
{ "name": "acme", "address": "123 Carrot Street" }
541,
{ "name": "acme", "address": "123 Carrot Street" }
542Trả về true nếu phương thức HTTP là GET/POST/PATCH/PUT/DELETE/HEAD.
{ "name": "acme", "address": "123 Carrot Street" }
543Trả về một hàm băm chứa các tiêu đề được liên kết với yêu cầu.
{ "name": "acme", "address": "123 Carrot Street" }
544Số cổng (số nguyên) được sử dụng cho yêu cầu.
{ "name": "acme", "address": "123 Carrot Street" }
545Trả về một chuỗi chứa giao thức được sử dụng cộng với ". //", ví dụ "http. //".
{ "name": "acme", "address": "123 Carrot Street" }
546Phần chuỗi truy vấn của URL, tôi. e. , mọi thứ sau "?".
{ "name": "acme", "address": "123 Carrot Street" }
547Địa chỉ IP của khách hàng.
{ "name": "acme", "address": "123 Carrot Street" }
548Toàn bộ URL được sử dụng cho yêu cầu
10. 1. 1
{ "name": "acme", "address": "123 Carrot Street" }
549,
{ "name": "acme", "address": "123 Carrot Street" }
550 và
{ "name": "acme", "address": "123 Carrot Street" }
551

Rails thu thập tất cả các tham số được gửi cùng với yêu cầu trong hàm băm

{ "name": "acme", "address": "123 Carrot Street" }
31, cho dù chúng được gửi như một phần của chuỗi truy vấn hay nội dung bài đăng. Đối tượng yêu cầu có ba trình truy cập cung cấp cho bạn quyền truy cập vào các tham số này tùy thuộc vào nguồn gốc của chúng. Hàm băm
{ "name": "acme", "address": "123 Carrot Street" }
550 chứa các tham số được gửi như một phần của chuỗi truy vấn trong khi hàm băm
{ "name": "acme", "address": "123 Carrot Street" }
551 chứa các tham số được gửi như một phần của nội dung bài đăng. Hàm băm
{ "name": "acme", "address": "123 Carrot Street" }
549 chứa các tham số được định tuyến nhận ra là một phần của đường dẫn đến bộ điều khiển và hành động cụ thể này

10. 2 Đối tượng
{ "name": "acme", "address": "123 Carrot Street" }
529

Đối tượng phản hồi thường không được sử dụng trực tiếp, nhưng được xây dựng trong quá trình thực hiện hành động và hiển thị dữ liệu được gửi lại cho người dùng, nhưng đôi khi - như trong bộ lọc sau - có thể hữu ích khi truy cập vào phản hồi . Một số phương thức truy cập này cũng có setters, cho phép bạn thay đổi giá trị của chúng. Để có danh sách đầy đủ các phương thức có sẵn, hãy tham khảo tài liệu Rails API và Tài liệu Rack

Thuộc tính của
{ "name": "acme", "address": "123 Carrot Street" }
529Mục đích
{ "name": "acme", "address": "123 Carrot Street" }
558Đây là chuỗi dữ liệu được gửi lại cho khách hàng. Đây thường là HTML.
{ "name": "acme", "address": "123 Carrot Street" }
559Mã trạng thái HTTP cho phản hồi, như 200 cho yêu cầu thành công hoặc 404 cho tệp không tìm thấy.
{ "name": "acme", "address": "123 Carrot Street" }
560URL khách hàng đang được chuyển hướng đến, nếu có.
{ "name": "acme", "address": "123 Carrot Street" }
561Loại nội dung của phản hồi.
{ "name": "acme", "address": "123 Carrot Street" }
562Bộ ký tự đang được sử dụng cho phản hồi. Mặc định là "utf-8".
{ "name": "acme", "address": "123 Carrot Street" }
543Tiêu đề được sử dụng cho phản hồi

Nếu bạn muốn đặt tiêu đề tùy chỉnh cho phản hồi thì

{ "name": "acme", "address": "123 Carrot Street" }
564 là nơi để thực hiện. Thuộc tính tiêu đề là một hàm băm ánh xạ tên tiêu đề thành giá trị của chúng và Rails sẽ tự động đặt một số trong số chúng. Nếu bạn muốn thêm hoặc thay đổi tiêu đề, chỉ cần gán nó cho
{ "name": "acme", "address": "123 Carrot Street" }
564 theo cách này

{ "name": "acme", "address": "123 Carrot Street" }
44Bản sao

Trong trường hợp trên, sẽ hợp lý hơn nếu sử dụng trực tiếp trình thiết lập

{ "name": "acme", "address": "123 Carrot Street" }
561

Rails đi kèm với ba cơ chế xác thực HTTP tích hợp

  • Xác thực cơ bản
  • Xác thực thông báo
  • Xác thực mã thông báo

Xác thực cơ bản HTTP là một sơ đồ xác thực được hỗ trợ bởi phần lớn các trình duyệt và ứng dụng khách HTTP khác. Ví dụ: hãy xem xét phần quản trị sẽ chỉ khả dụng bằng cách nhập tên người dùng và mật khẩu vào cửa sổ hộp thoại cơ bản HTTP của trình duyệt. Sử dụng xác thực tích hợp khá dễ dàng và chỉ yêu cầu bạn sử dụng một phương pháp,

{ "name": "acme", "address": "123 Carrot Street" }
567

{ "name": "acme", "address": "123 Carrot Street" }
45Bản sao

Với điều này, bạn có thể tạo các bộ điều khiển không gian tên kế thừa từ

{ "name": "acme", "address": "123 Carrot Street" }
568. Do đó, bộ lọc sẽ được chạy cho tất cả các hành động trong các bộ điều khiển đó, bảo vệ chúng bằng xác thực cơ bản HTTP

Xác thực thông báo HTTP vượt trội hơn so với xác thực cơ bản vì nó không yêu cầu máy khách gửi mật khẩu không được mã hóa qua mạng (mặc dù xác thực cơ bản HTTP an toàn hơn HTTPS). Sử dụng xác thực thông báo với Rails khá dễ dàng và chỉ yêu cầu sử dụng một phương thức,

{ "name": "acme", "address": "123 Carrot Street" }
569

{ "name": "acme", "address": "123 Carrot Street" }
46Bản sao

Như đã thấy trong ví dụ trên, khối

{ "name": "acme", "address": "123 Carrot Street" }
569 chỉ nhận một đối số - tên người dùng. Và khối trả về mật khẩu. Trả lại
{ "name": "acme", "address": "123 Carrot Street" }
571 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
878 từ
{ "name": "acme", "address": "123 Carrot Street" }
569 sẽ gây ra lỗi xác thực

Xác thực mã thông báo HTTP là một sơ đồ cho phép sử dụng mã thông báo Bearer trong tiêu đề HTTP

{ "name": "acme", "address": "123 Carrot Street" }
574. Có nhiều định dạng mã thông báo có sẵn và việc mô tả chúng nằm ngoài phạm vi của tài liệu này

Ví dụ: giả sử bạn muốn sử dụng mã thông báo xác thực đã được cấp trước để thực hiện xác thực và truy cập. Việc triển khai xác thực mã thông báo với Rails khá dễ dàng và chỉ yêu cầu sử dụng một phương thức,

{ "name": "acme", "address": "123 Carrot Street" }
575

{ "name": "acme", "address": "123 Carrot Street" }
47Bản sao

Như đã thấy trong ví dụ trên, khối

{ "name": "acme", "address": "123 Carrot Street" }
575 có hai đối số - mã thông báo và một
{ "name": "acme", "address": "123 Carrot Street" }
893 chứa các tùy chọn đã được phân tích cú pháp từ tiêu đề HTTP
{ "name": "acme", "address": "123 Carrot Street" }
574. Khối sẽ trả về
{ "name": "acme", "address": "123 Carrot Street" }
579 nếu xác thực thành công. Trả lại
{ "name": "acme", "address": "123 Carrot Street" }
571 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
878 trên đó sẽ gây ra lỗi xác thực

Đôi khi bạn muốn gửi tệp cho người dùng thay vì hiển thị trang HTML. Tất cả các bộ điều khiển trong Rails đều có các phương thức

{ "name": "acme", "address": "123 Carrot Street" }
582 và
{ "name": "acme", "address": "123 Carrot Street" }
583, cả hai sẽ truyền dữ liệu đến máy khách.
{ "name": "acme", "address": "123 Carrot Street" }
583 là một phương pháp tiện lợi cho phép bạn cung cấp tên của tệp trên đĩa và nó sẽ truyền nội dung của tệp đó cho bạn

Để truyền dữ liệu đến máy khách, hãy sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
582

{ "name": "acme", "address": "123 Carrot Street" }
48Bản sao

Hành động

{ "name": "acme", "address": "123 Carrot Street" }
586 trong ví dụ trên sẽ gọi một phương thức riêng thực sự tạo tài liệu PDF và trả về dưới dạng một chuỗi. Chuỗi này sau đó sẽ được truyền trực tuyến tới máy khách dưới dạng tệp tải xuống và tên tệp sẽ được đề xuất cho người dùng. Đôi khi khi truyền tệp đến người dùng, bạn có thể không muốn họ tải xuống tệp. Lấy hình ảnh, ví dụ, có thể được nhúng vào các trang HTML. Để thông báo cho trình duyệt rằng một tệp không được tải xuống, bạn có thể đặt tùy chọn
{ "name": "acme", "address": "123 Carrot Street" }
587 thành "nội tuyến". Giá trị ngược lại và mặc định cho tùy chọn này là "tệp đính kèm"

12. 1 Gửi tập tin

Nếu bạn muốn gửi một tệp đã tồn tại trên đĩa, hãy sử dụng phương pháp

{ "name": "acme", "address": "123 Carrot Street" }
583

{ "name": "acme", "address": "123 Carrot Street" }
49Bản sao

Thao tác này sẽ đọc và phát trực tuyến tệp 4 kB tại thời điểm đó, tránh tải toàn bộ tệp vào bộ nhớ cùng một lúc. Bạn có thể tắt tính năng phát trực tuyến bằng tùy chọn

{ "name": "acme", "address": "123 Carrot Street" }
589 hoặc điều chỉnh kích thước khối bằng tùy chọn
{ "name": "acme", "address": "123 Carrot Street" }
590

Nếu

{ "name": "acme", "address": "123 Carrot Street" }
591 không được chỉ định, nó sẽ được đoán từ phần mở rộng tệp được chỉ định trong
{ "name": "acme", "address": "123 Carrot Street" }
592. Nếu loại nội dung không được đăng ký cho tiện ích mở rộng, thì
{ "name": "acme", "address": "123 Carrot Street" }
593 sẽ được sử dụng

Hãy cẩn thận khi sử dụng dữ liệu đến từ máy khách (thông số, cookie, v.v. ) để xác định vị trí tệp trên đĩa, vì đây là rủi ro bảo mật có thể cho phép ai đó có quyền truy cập vào các tệp mà họ không có ý định truy cập

Bạn không nên truyền các tệp tĩnh qua Rails nếu thay vào đó, bạn có thể giữ chúng trong một thư mục chung trên máy chủ web của mình. Sẽ hiệu quả hơn nhiều nếu cho phép người dùng tải xuống tệp trực tiếp bằng Apache hoặc máy chủ web khác, giữ cho yêu cầu không đi qua toàn bộ ngăn xếp Rails một cách không cần thiết

12. 2 lượt tải xuống RESTful

Mặc dù

{ "name": "acme", "address": "123 Carrot Street" }
582 hoạt động tốt, nhưng nếu bạn đang tạo một ứng dụng RESTful thì thường không cần thiết có các hành động riêng để tải xuống tệp. Theo thuật ngữ REST, tệp PDF từ ví dụ trên có thể được coi là một biểu diễn khác của tài nguyên máy khách. Rails cung cấp một cách dễ dàng và khá mượt mà để thực hiện "RESTful downloads". Đây là cách bạn có thể viết lại ví dụ để tải xuống PDF là một phần của hành động
{ "name": "acme", "address": "123 Carrot Street" }
595 mà không có bất kỳ luồng nào

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
0Bản sao

Để ví dụ này hoạt động, bạn phải thêm loại PDF MIME vào Rails. Điều này có thể được thực hiện bằng cách thêm dòng sau vào tệp

{ "name": "acme", "address": "123 Carrot Street" }
596

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
1Bản sao

Các tệp cấu hình không được tải lại trên mỗi yêu cầu, vì vậy bạn phải khởi động lại máy chủ để các thay đổi của chúng có hiệu lực

Giờ đây, người dùng có thể yêu cầu nhận phiên bản PDF của ứng dụng khách chỉ bằng cách thêm ". pdf" vào URL

12. 3 Phát trực tiếp dữ liệu tùy ý

Rails cho phép bạn truyền phát nhiều hơn chỉ các tệp. Trên thực tế, bạn có thể truyền bất cứ thứ gì bạn muốn trong một đối tượng phản hồi. Mô-đun

{ "name": "acme", "address": "123 Carrot Street" }
597 cho phép bạn tạo kết nối liên tục với trình duyệt. Sử dụng mô-đun này, bạn sẽ có thể gửi dữ liệu tùy ý tới trình duyệt tại các thời điểm cụ thể

12. 3. 1 Kết hợp phát trực tiếp

Bao gồm

{ "name": "acme", "address": "123 Carrot Street" }
597 bên trong lớp trình điều khiển của bạn sẽ cung cấp cho tất cả các hành động bên trong bộ điều khiển khả năng truyền dữ liệu. Bạn có thể trộn trong mô-đun như vậy

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
2Bản sao

Đoạn mã trên sẽ giữ kết nối liên tục với trình duyệt và gửi 100 tin nhắn

{ "name": "acme", "address": "123 Carrot Street" }
599, mỗi tin nhắn cách nhau một giây

Có một vài điều cần chú ý trong ví dụ trên. Chúng tôi cần đảm bảo đóng luồng phản hồi. Quên đóng luồng sẽ khiến ổ cắm mở mãi mãi. Chúng tôi cũng phải đặt loại nội dung thành

{ "name": "acme", "address": "123 Carrot Street" }
700 trước khi ghi vào luồng phản hồi. Điều này là do không thể ghi tiêu đề sau khi phản hồi đã được thực hiện (khi
{ "name": "acme", "address": "123 Carrot Street" }
701 trả về giá trị trung thực), điều này xảy ra khi bạn
{ "name": "acme", "address": "123 Carrot Street" }
702 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
703 luồng phản hồi

12. 3. 2 Ví dụ Cách sử dụng

Giả sử bạn đang tạo một máy hát Karaoke và người dùng muốn lấy lời bài hát cho một bài hát cụ thể. Mỗi

{ "name": "acme", "address": "123 Carrot Street" }
704 có một số dòng cụ thể và mỗi dòng cần thời gian để
{ "name": "acme", "address": "123 Carrot Street" }
705 hát xong

Nếu muốn trả lời lời bài hát theo kiểu Karaoke (chỉ gửi câu khi ca sĩ đã hát xong câu trước) thì ta có thể sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
597 như sau

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
3Bản sao

Đoạn mã trên chỉ gửi dòng tiếp theo sau khi ca sĩ đã hoàn thành dòng trước đó

12. 3. 3 cân nhắc phát trực tuyến

Truyền dữ liệu tùy ý là một công cụ cực kỳ mạnh mẽ. Như đã trình bày trong các ví dụ trước, bạn có thể chọn thời điểm và nội dung gửi qua luồng phản hồi. Tuy nhiên bạn cũng cần lưu ý những điều sau

  • Mỗi luồng phản hồi tạo một luồng mới và sao chép các biến cục bộ của luồng từ luồng ban đầu. Có quá nhiều biến cục bộ của luồng có thể tác động tiêu cực đến hiệu suất. Tương tự, một số lượng lớn các chủ đề cũng có thể cản trở hiệu suất
  • Không thể đóng luồng phản hồi sẽ khiến ổ cắm tương ứng mở mãi mãi. Đảm bảo gọi
    { "name": "acme", "address": "123 Carrot Street" }
    
    707 bất cứ khi nào bạn đang sử dụng luồng phản hồi
  • Máy chủ WEBrick đệm tất cả các phản hồi và do đó bao gồm cả
    { "name": "acme", "address": "123 Carrot Street" }
    
    597 sẽ không hoạt động. Bạn phải sử dụng máy chủ web không tự động đệm phản hồi

Rails giữ một tệp nhật ký cho từng môi trường trong thư mục

{ "name": "acme", "address": "123 Carrot Street" }
709. Chúng cực kỳ hữu ích khi gỡ lỗi những gì đang thực sự diễn ra trong ứng dụng của bạn, nhưng trong một ứng dụng trực tiếp, bạn có thể không muốn mọi bit thông tin được lưu trữ trong tệp nhật ký

13. 1 Tham số Lọc

Bạn có thể lọc ra các tham số yêu cầu nhạy cảm khỏi các tệp nhật ký của mình bằng cách thêm chúng vào

{ "name": "acme", "address": "123 Carrot Street" }
710 trong cấu hình ứng dụng. Các thông số này sẽ được đánh dấu [LỌC] trong nhật ký

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
4Bản sao

Các thông số đã cung cấp sẽ được lọc ra bằng cách khớp một phần cụm từ thông dụng. Rails thêm danh sách các bộ lọc mặc định, bao gồm

{ "name": "acme", "address": "123 Carrot Street" }
711,
{ "name": "acme", "address": "123 Carrot Street" }
712 và
{ "name": "acme", "address": "123 Carrot Street" }
713, trong bộ khởi tạo thích hợp (
{ "name": "acme", "address": "123 Carrot Street" }
714) để xử lý các tham số ứng dụng điển hình như
{ "name": "acme", "address": "123 Carrot Street" }
715,
{ "name": "acme", "address": "123 Carrot Street" }
716 và
{ "name": "acme", "address": "123 Carrot Street" }
717

13. Lọc 2 chuyển hướng

Đôi khi, bạn nên lọc ra khỏi các tệp nhật ký một số vị trí nhạy cảm mà ứng dụng của bạn đang chuyển hướng đến. Bạn có thể làm điều đó bằng cách sử dụng tùy chọn cấu hình

{ "name": "acme", "address": "123 Carrot Street" }
718

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
5Bản sao

Bạn có thể đặt nó thành Chuỗi, Regexp hoặc mảng của cả hai

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
6Bản sao

Các URL phù hợp sẽ được đánh dấu là '[LỌC]'

Rất có thể ứng dụng của bạn sẽ có lỗi hoặc có ngoại lệ cần được xử lý. Ví dụ: nếu người dùng nhấp vào liên kết đến tài nguyên không còn tồn tại trong cơ sở dữ liệu, Bản ghi Hoạt động sẽ đưa ra ngoại lệ

{ "name": "acme", "address": "123 Carrot Street" }
719

Xử lý ngoại lệ mặc định của Rails hiển thị thông báo "500 Server Error" cho tất cả các ngoại lệ. Nếu yêu cầu được thực hiện cục bộ, một dấu vết đẹp và một số thông tin bổ sung sẽ được hiển thị, vì vậy bạn có thể tìm ra lỗi sai và xử lý nó. Nếu yêu cầu là từ xa, Rails sẽ chỉ hiển thị một thông báo "500 Server Error" đơn giản cho người dùng hoặc "404 Not Found" nếu có lỗi định tuyến hoặc không thể tìm thấy bản ghi. Đôi khi, bạn có thể muốn tùy chỉnh cách phát hiện và hiển thị các lỗi này cho người dùng. Có một số cấp độ xử lý ngoại lệ có sẵn trong ứng dụng Rails

14. 1 Mẫu 500 và 404 mặc định

Theo mặc định, trong môi trường sản xuất, ứng dụng sẽ hiển thị thông báo lỗi 404 hoặc 500. Trong môi trường phát triển, tất cả các ngoại lệ chưa được xử lý đều được nêu ra một cách đơn giản. Các thông báo này được chứa trong các tệp HTML tĩnh trong thư mục công cộng, lần lượt là

{ "name": "acme", "address": "123 Carrot Street" }
720 và
{ "name": "acme", "address": "123 Carrot Street" }
721. Bạn có thể tùy chỉnh các tệp này để thêm một số thông tin và kiểu dáng bổ sung, nhưng hãy nhớ rằng chúng là HTML tĩnh; . e. bạn không thể sử dụng ERB, SCSS, CoffeeScript hoặc bố cục cho chúng

14. 2
{ "name": "acme", "address": "123 Carrot Street" }
722

Nếu bạn muốn làm điều gì đó phức tạp hơn một chút khi bắt lỗi, bạn có thể sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
722, xử lý các ngoại lệ của một loại nhất định (hoặc nhiều loại) trong toàn bộ bộ điều khiển và các lớp con của nó

Khi một ngoại lệ xảy ra và bị bắt bởi lệnh

{ "name": "acme", "address": "123 Carrot Street" }
722, đối tượng ngoại lệ sẽ được chuyển đến trình xử lý. Trình xử lý có thể là một phương thức hoặc một đối tượng
{ "name": "acme", "address": "123 Carrot Street" }
725 được truyền cho tùy chọn
{ "name": "acme", "address": "123 Carrot Street" }
726. Bạn cũng có thể sử dụng một khối trực tiếp thay vì một đối tượng rõ ràng
{ "name": "acme", "address": "123 Carrot Street" }
725

Đây là cách bạn có thể sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
722 để chặn tất cả lỗi
{ "name": "acme", "address": "123 Carrot Street" }
719 và xử lý chúng

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
7Bản sao

Tất nhiên, ví dụ này là bất cứ điều gì ngoại trừ phức tạp và hoàn toàn không cải thiện việc xử lý ngoại lệ mặc định, nhưng một khi bạn có thể nắm bắt được tất cả các ngoại lệ đó, bạn có thể tự do làm bất cứ điều gì bạn muốn với chúng. Ví dụ: bạn có thể tạo các lớp ngoại lệ tùy chỉnh sẽ bị ném khi người dùng không có quyền truy cập vào một phần nhất định trong ứng dụng của bạn

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
8Bản sao

Sử dụng

{ "name": "acme", "address": "123 Carrot Street" }
722 với
{ "name": "acme", "address": "123 Carrot Street" }
731 hoặc
{ "name": "acme", "address": "123 Carrot Street" }
732 sẽ gây ra tác dụng phụ nghiêm trọng vì nó ngăn Rails xử lý ngoại lệ đúng cách. Như vậy, không nên làm như vậy trừ khi có lý do chính đáng

Khi chạy trong môi trường sản xuất, tất cả lỗi

{ "name": "acme", "address": "123 Carrot Street" }
719 hiển thị trang lỗi 404. Trừ khi bạn cần một hành vi tùy chỉnh, bạn không cần phải xử lý việc này

Một số ngoại lệ chỉ có thể giải cứu được từ lớp

{ "company": { "name": "acme", "address": "123 Carrot Street" } }
9, vì chúng được đưa ra trước khi bộ điều khiển được khởi tạo và hành động được thực thi

Nếu bạn muốn đảm bảo rằng giao tiếp với bộ điều khiển của mình chỉ có thể thực hiện được qua HTTPS, thì bạn nên làm như vậy bằng cách bật phần mềm trung gian

{ "name": "acme", "address": "123 Carrot Street" }
735 qua
{ "name": "acme", "address": "123 Carrot Street" }
736 trong cấu hình môi trường của mình

Nhận xét

Bạn được khuyến khích giúp cải thiện chất lượng của hướng dẫn này

Vui lòng đóng góp nếu bạn thấy bất kỳ lỗi chính tả hoặc lỗi thực tế nào. Để bắt đầu, bạn có thể đọc phần đóng góp tài liệu của chúng tôi

Bạn cũng có thể tìm thấy nội dung không đầy đủ hoặc nội dung không được cập nhật. Vui lòng thêm bất kỳ tài liệu còn thiếu nào cho chính. Đảm bảo kiểm tra Hướng dẫn cạnh trước để xác minh xem sự cố đã được khắc phục hay chưa trên nhánh chính. Kiểm tra Hướng dẫn Hướng dẫn Ruby on Rails để biết phong cách và quy ước

Nếu vì bất kỳ lý do gì mà bạn phát hiện ra điều gì đó cần khắc phục nhưng không thể tự vá nó, vui lòng mở một vấn đề

Và cuối cùng nhưng không kém phần quan trọng, bất kỳ loại thảo luận nào liên quan đến tài liệu Ruby on Rails đều rất được hoan nghênh trên Diễn đàn Ruby on Rails chính thức