Đối với các lập trình viên web nói chung thì chúng ta không thể nào mà không nghe đến các từ như get hoặc post, nó thực sự rất phổ biển
SUMARY
Đầu tiên phải nói đến là có tất cả 9 loại request, get và post là 2 loại thông dụng được sử dụng nhiều. GET: được sử dụng để lấy thông tin từ sever theo URI đã cung cấp. HEAD: giống với GET nhưng response trả về không có body, chỉ có header POST: gửi thông tin tới sever thông qua các biểu mẫu http( đăng kí chả hạn..) PUT: ghi đè tất cả thông tin của đối tượng với những gì được gửi lên PATCH: ghi đè các thông tin được thay đổi của đối tượng. DELETE: xóa tài nguyên trên server. CONNECT: thiết lập một kết nối tới server theo URI. OPTIONS: mô tả các tùy chọn giao tiếp cho resource. TRACE: thực hiện một bài test loop - back theo đường dẫn đến resource.
GET VS POST
2 loại request get post gần như đều rất quen thuộc với chúng ta. với một ứng dụng web được thiết kế theo restful thì get chỉ dùng để lấy dữ liệu và post chỉ dùng để đẩy dữ liệu lên. Nhưng, khi đi phỏng vấn thì chúng ta sẽ thường được hỏi: "Liệu get có thể được dùng để đấy dữ liệu lên hay post có thể được dùng để lấy dữ liệu về hay không ?" thú thật với các bạn là trước đây tôi đã trả lời là không thể :man_vampire: Hoàn toàn có thể các bạn nhé. Nhưng có chúng ta không nên sử dụng như vậy, nó phá vỡ các quy tắc thiết kế. Một chút khác biệt dễ nhận thấy giữa get và post là get thì không có body. Khi dùng get để truyền dữ liệu lên sever chúng ta thấy rằng tất cả các paramater đều bị hiển thị trên url của request, xét về khía cạnh bảo mật thì điều này thật là tệ. Post thì khác, nó giấu parameters trong body và mã hóa chúng đi, ngăn cản các phần tử trung gian ăn cắp nội dung. Nhưng post chỉ có tính an toàn đối với client, còn với sever thì lại khác. Các method như post, put, delete bị coi là unsafe và not idempotent cho server.
POST/PUT/PATCH
Điểm khác biệt giữ post và put đơn giản là put là idempotent còn post thì không, bạn sẽ nhận được thông báo lỗi khi gửi một request post với cùng 1 nội dung 2 lần nhưng put thì không, nó luôn trả về kết quả như nhau. post: tạo mới put: ghi đè(toàn bộ) hoặc tạo mới 1 resource patch: cập một 1 phần của resource
SAFE
một method được coi là safe khi nó không làm thay đổi trạng thái "sate" của server. Nói cách khác, an toàn là chỉ đọc mà không làm thay đổi bất kì điều gì. Các method được coi là safe chỉ có: GET, HEAD và OPTIONS. Unsafe: PUT, DELETE, POST và PATCH.
IDEMPOTENT
các method được coi là idempotent khi nó có thể thực hiên n + 1 lần mà vẫn trả lại 1 kết quả như ban đầu.
vì điều này nên các method safe thì đều idempotent. Nhưng unsafe chưa chắc đã idempotent.
1 số lưu ý: header dài tối đa 8kb và cũng phụ thuộc cả vào trình duyệt body thì limit của nó tùy trình duyệt. url không dài quá 2 nghìn kí tự (ror)
Trong quá trình đi làm, nhất là nếu làm frontend thì chắc chắn sẽ có một lúc nào đó các bạn bị Chrome (trình duyệt nói chung) chửi vô mặt những thứ đại loại liên quan đến cái của nợ Access-Control-Allow-Origin header.
Tôi đã từng nghĩ đại đa số các bạn làm Web developer đều hiểu cái này rồi nhưng sự thật không hẳn là như vậy. Sau khi tổ chức một cuộc điều tra nho nhỏ, thì có vẻ như các bạn backend hiểu về CORS nhiều hơn là frontend. Và có kha khá bạn không hiểu, hay hiểu một cách mơ hồ, không thể giải thích được về CORS.
Và vì thế, tada, tôi viết bài viết này để lỡ chẳng may có bạn nào chưa hiểu thì cũng có thể vớt vát được chút xíu sau khi đọc xong!
Sinh ra CORS chi cho phức tạp vậy?
Mọi việc trên đời này xảy ra đều có nguồn cơn của nó và cái của nợ CORS cũng không ngoại lệ.
Đầu tiên phải nói đến same origin policy, đây là một security concept quan trọng được hiện thực trên các thể loại trình duyệt nhằm ngăn chặn JavaScript code có thể tạo ra những request đến những nguồn khác với nguồn mà nó được trả về (ví dụ đơn giản như request tới những domain khác), và cách để so sánh same origin được mô tả ở đây, tuy nhiên để nói một cách đơn giản thì domain sẽ phải giống nhau từ đầu tới cuối từ protocol đến host, port.
Tại sao việc này nguy hiểm, thì các bạn cứ nghĩ đơn giản, nếu các bạn vô Facebook, trong khi đó ở một tab khác các bạn mở một trang web chứa mã độc. Tab Facebook sử dụng JavaScript để request lên server, nếu không có same origin policy, JavaScript ở web chứa mã độc kia cũng có thể tạo request lên server của Facebook với resource của tab Facebook, vì thế trình duyệt phải có cơ chế để phân biệt JavaScript của nguồn nào thì được access vào resource của nguồn nào.
Okay, đó là cách để bảo vệ người dùng, tuy nhiên thì nó gây ra không ít hạn chế cho việc giao tiếp giữa client và server mặc dù chúng đều là những nguồn có thể tin tưởng được (ví dụ client là portal.codeaholicguy.com và server là api.codeaholicguy.com, hai domain này chắc chắn là không same origin rồi).
CORS (hay nói một cách giông dài là Cross-Origin Resource Sharing) là một kĩ thuật được sinh ra để làm cho việc tương tác giữa client và server được dễ dàng hơn, nó cho phép JavaScript ở một trang web có thể tạo request lên một REST API được host ở một domain khác.
Cơ chế hoạt động của CORS như thế nào?
Trong trường hợp đơn giản nhất, phía client (tức là cái web app chạy ở browser đó) sẽ tạo request GET, POST, PUT, HEAD, etc để yêu cầu server làm một việc gì đó. Những request này sẽ được đính kèm một header tên là Origin để chỉ định origin của client code (giá trị của header này chính là domain của trang web).
Server sẽ xem xét Origin để biết được nguồn này có phải là nguồn hợp lệ hay không. Nếu hợp lệ, server sẽ trả về response kèm với header Access-Control-Allow-Origin. Header này sẽ cho biết xem client có phải là nguồn hợp lệ để browser tiếp tục thực hiện quá trình request.
Trong trường hợp thông thường, Access-Control-Allow-Origin sẽ có giá trị giống như Origin, một số trường hợp giá trị của Access-Control-Allow-Origin sẽ nhìn giống giống như Regex hay chỉ đơn giản là *, tuy nhiên thì cách dùng * thường được coi là không an toàn, ngoại trừ trường hợp API của bạn được public hoàn toàn và ai cũng có thể truy cập được.
Và như thế, nếu không có header Access-Control-Allow-Origin hoặc giá trị của nó không hợp lệ thì browser sẽ chửi vào mặt chúng ta.
Vẫn chưa hết đâu, các bạn phải biết về Pre-flight requests nữa!
Khi bạn thực hiện những request ảnh hưởng tới data như POST, PUT, DELETE, etc thì browser sẽ tự động thưc hiện một request gọi là preflight request trước khi thực sự thực hiện request để kiểm tra xem phía server đã thực hiện CORS hay chưa, cũng như để biết được rằng request này có hợp lệ hay không. Ngoài ra thì nếu bạn có thêm những custom header vào trong request thì việc gửi một preflight request cũng là cần thiết.
Preflight request được gửi lên server với dạng là OPTIONS (đây là lý do tại sao khi bạn debug ở client bạn thường thấy có hai request giống nhau nhưng khác request method, một cái là OPTIONS một cái là method thật sự bạn muốn gửi).
Ví dụ bạn muốn gửi request DELETE lên server. Browser sẽ tự tạo một request OPTIONS sẽ hỏi xem server có cho phép việc gửi request DELETE hay không. Nếu server cho phép, nó sẽ gửi về response đính kèm những header như Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Max-Age, etc.
Access-Control-Allow-Methods: mô tả những method nào client có thể gửi đi.
Access-Control-Max-Age: mô tả thời gian hợp lệ của preflight request, nếu quá hạn, browser sẽ tự tạo một preflight request mới.
Sau đó browser sẽ có thể gửi request DELETE và nhận response như bình thường. Và ngược lại, browser sẽ chửi vào mặt bạn.
Kết luận
Và đó là tất cả những gì tôi biết về CORS, hy vọng nó sẽ giúp ích được cho các bạn, cũng như lý giải được thắc mắc của một số bạn về CORS từ trước đến giờ.
Nếu các bạn có góp ý gì thêm hay chủ đề nào hay ho mà các bạn muốn tôi viết thì đừng quên để lại cho tôi một lời nhắn nho nhỏ ở phần comment bên dưới nhé.
Ví dụ e đàng dùng nodejs nếu e không dùng package CORS thì request trang khác không có quyền truy cập đúng ko anh còn nếu e có sữ dụng thì những trang khác có quyền truy cập đúng ko anh
Chào anh , cho em hỏi sao em lại bị xóa comments vậy ạ. em có vào để xem anh trả lời thì thấy bị anh xóa. anh cho hỏi hỏi lí do được không ạ. Câu hỏi của em là dù có truy vấn từ site khác nhưng đâu có thể gửi kèm cookie từ trang khách thì đâu có nguy hiểm như đoạn nay a nói. “JavaScript ở web chứa mã độc kia cũng có thể tạo request lên server của Facebook với resource của tab Facebook, “
sao lại có nhỉ lại hiện lên rồi . sorry chắc em nhầm :3 vừa rồi ctrl+ F tìm mà không thấy giờ lại có
Cho em hỏi đoạn này ” Tab Facebook sử dụng JavaScript để request lên server, nếu không có same origin policy, JavaScript ở web chứa mã độc kia cũng có thể tạo request lên server của Facebook với resource của tab Facebook” . ví dụ request tới facebook.com/me thì đâu lấy được gì vì cơ bản request đó đâu có kèm cookie facebook. tương tự với các trang khác. Em có reuqest như vậy bản chất là trình duyệt trả về kết quả lỗi nhưng vẫn sẽ thực hiện
Bạn hiểu đơn giản thế này. Ví dụ bạn truy cập từ trình duyệt bình thường vào api.codeaholicguy.com thì ra result còn dùng javascript truy cập từ trang portal.codeaholicguy.com tới api thì sẽ bị chặn do CORS. cách postman truy cập là giống như cách 1 đó
Bạn bên trên giải thích có ý đúng đó, như a có giải thích bên trên, Browser sẽ thực hiện cơ chế preflight request để kiểm tra cors, còn với postman nó ko được implement cơ chế preflight request mà request sẽ được gọi trực tiếp luôn vì postman ko cần kiểm tra policy về cors
Hi am cho me hỏi có cách nào chặn OPTIONS requests k anh, nhiều khi nó làm duplicate action mà ta đã code á. Ví dụ send mail chẳn hạn ?
A Multipurpose Internet Mail Extensions (MIME) type is a standard that indicates the nature and format of a document, file, or assortment of bytes. It is defined and standardized in IETF RFC 6838.
Browsers use the MIME type, not the file extension, to determine how to process a URL — it is important that servers send the correct MIME type in the response's Content-Typeheader.
A MIME type consists of a type and a subtype — two strings separated by /. No whitespace is allowed. The type represents the category and can be a discrete or a multipart type. The subtype is specific to each type.
MIME types are case-insensitive but traditionally written in lowercase.
Multipart types indicate a category of document broken into pieces, often with different MIME types. They represent a composite document. With the exception of multipart/form-data, used in the POST method of HTML Forms, and multipart/byteranges, used with 206Partial Content to send part of a document, HTTP doesn't handle multipart documents in a special way: the message is transmitted to the browser (which will likely show a "Save As" window if it doesn't know how to display the document.)
This is the default for binary files. As it means unknown binary file, browsers usually don't execute it, or even ask if it should be executed. They treat it as if the Content-Dispositionheader was set to attachment, and propose a "Save As" dialog.
This is the default for textual files. Even if it really means unknown textual file, browsers assume they can display it.
Note that text/plain does not mean any kind of textual data. If they expect a specific kind of textual data, they will likely not consider it a match. Specifically if they download a text/plain file from a <link> element declaring a CSS files, they will not recognize it as a valid CSS files if presented with text/plain. The CSS mime type text/css must be used.
CSS files used to style a Web page must be sent with text/css. If a server doesn't recognize the .css suffix for CSS files, it may send them with text/plain or application/octet-stream MIME types. If so, they won't be recognized as CSS by most browsers and will be ignored.
All HTML content should be served with this type. Alternative MIME types for XHTML (like application/xhtml+xml) are mostly useless nowadays.
Note: Use application/xml or application/xhtml+xml if you want XML’s strict parsing rules, <![CDATA[…]]> sections, or elements that aren't from HTML/SVG/MathML namespaces.
Servers should use text/javascript for JavaScript resources. Servers should not use other JavaScript MIME types for JavaScript resources, and must not use non-JavaScript MIME types.
The other JavaScript MIME types that should not be used are defined in the MIME Sniffing Standard as follows:
The MIME type of audiovisual files mostly indicate the container formats. The most common ones on the Web are:
MIME type
Audio or video type
audio/wave audio/wav audio/x-wav audio/x-pn-wav
An audio file in the WAVE container format. The PCM audio codec (WAVE codec "1") is often supported, but other codecs have limited support (if any).
audio/webm
An audio file in the WebM container format. Vorbis and Opus are the most common audio codecs.
video/webm
A video file, possibly with audio, in the WebM container format. VP8 and VP9 are the most common video codecs; Vorbis and Opus the most common audio codecs.
audio/ogg
An audio file in the OGG container format. Vorbis is the most common audio codec used in such a container.
video/ogg
A video file, possibly with audio, in the OGG container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec.
application/ogg
An audio or video file using the OGG container format. Theora is the usual video codec used within it; Vorbis is the usual audio codec.
The multipart/form-data type can be used when sending the values of a completed HTML Form from browser to server.
As a multipart document format, it consists of different parts, delimited by a boundary (a string starting with a double dash --). Each part is its own entity with its own HTTP headers, Content-Disposition, and Content-Type for file uploading fields.
Content-Type: multipart/form-data; boundary=aBoundaryString
(other headers associated with the multipart document as a whole)
--aBoundaryString
Content-Disposition: form-data; name="myFile"; filename="img.jpg"
Content-Type: image/jpeg
(data)
--aBoundaryString
Content-Disposition: form-data; name="myField"
(data)
--aBoundaryString
(more subparts)
--aBoundaryString--
The following <form>:
<formaction="http://localhost:8000/"method="post"enctype="multipart/form-data"><label>Name: <inputname="myTextField"value="Test"></label><label><inputtype="checkbox"name="myCheckBox"> Check</label><label>Upload file: <inputtype="file"name="myFile"value="test.txt"></label><button>Send the file</button></form>
will send this message:
POST / HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------8721656041911415653955004498
Content-Length: 465
-----------------------------8721656041911415653955004498
Content-Disposition: form-data; name="myTextField"
Test
-----------------------------8721656041911415653955004498
Content-Disposition: form-data; name="myCheckBox"
on
-----------------------------8721656041911415653955004498
Content-Disposition: form-data; name="myFile"; filename="test.txt"
Content-Type: text/plain
Simple file.
-----------------------------8721656041911415653955004498--
The multipart/byteranges MIME type is used to send partial responses to the browser.
When the 206 Partial Content status code is sent, this MIME type indicates that the document is composed of several parts, one for each of the requested ranges. Like other multipart types, the Content-Type uses a boundary to separate the pieces. Each piece has a Content-Type header with its actual type and a Content-Range of the range it represents.
Importance of setting the correct MIME typeSection
Most web servers send unrecognized resources as the application/octet-stream MIME type. For security reasons, most browsers do not allow setting a custom default action for such resources, forcing the user to save it to disk to use it.
Some common incorrect server configurations:
RAR-compressed files. In this case, the ideal would be the true type of the original files; this is often impossible as .RAR files can hold several resources of different types. In this case, configure the server to send application/x-rar-compressed.
Proprietary file types. Avoid using application/octet-stream as most browsers do not allow defining a default behavior (like "Open in Word") for this generic MIME type. A specific type like application/vnd.mspowerpoint lets users open such files automatically in the presentation software of their choice.
In the absence of a MIME type, or in certain cases where browsers believe they are incorrect, browsers may perform MIME sniffing — guessing the correct MIME type by looking at the bytes of the resource.
Each browser performs MIME sniffing differently and under different circumstances. (For example, Safari will look at the file extension in the URL if the sent MIME type is unsuitable.) There are security concerns as some MIME types represent executable content. Servers can prevent MIME sniffing by sending the X-Content-Type-Options header.
Phần cơ chế hoạt động của CORS? Em ko hiểu chỗ: ” …để chỉ định origin của client code”, anh giải thích cho em đoạn này với ạ!
Sử dụng jsonp.