国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

HTTP協(xié)議介紹

這篇具有很好參考價(jià)值的文章主要介紹了HTTP協(xié)議介紹。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、認(rèn)識(shí)HTTP協(xié)議

HTTP協(xié)議是應(yīng)用層協(xié)議,它叫超文本傳輸協(xié)議。應(yīng)用層協(xié)議一般是我們自己自定義的,HTTP協(xié)議是計(jì)算機(jī)大佬們定義的一套現(xiàn)成的協(xié)議,因?yàn)樗约癏TTPS使用的場景非常多,現(xiàn)在已經(jīng)成為一套協(xié)議標(biāo)準(zhǔn),我們可以學(xué)習(xí)這套標(biāo)準(zhǔn)直接拿來使用。

當(dāng)我們?cè)谑褂脼g覽器上網(wǎng)時(shí),比如查閱文檔、看視頻聽音樂等,這些都是以網(wǎng)頁的形式呈現(xiàn)出來的,網(wǎng)頁本質(zhì)也是文件,它是以.html為后綴的文件,當(dāng)我們用瀏覽器瀏覽網(wǎng)頁時(shí),瀏覽器作為客戶端會(huì)向服務(wù)器發(fā)起HTTP請(qǐng)求,服務(wù)器會(huì)將網(wǎng)頁文件響應(yīng)回給客戶端。所以HTTP協(xié)議就是向特定的服務(wù)器申請(qǐng)?zhí)囟ㄙY源,把這些資源獲取到本地進(jìn)行展示或操作的。這里所說的資源指的是比如網(wǎng)頁資源、視頻資源、音頻資源,其實(shí)它們的本質(zhì)也是文件。

HTTP協(xié)議叫超文本傳輸協(xié)議其實(shí)是非常形象的,它可以傳輸文本比如網(wǎng)頁上我們看到的一大段一大段的文字,也可以傳輸類似于圖片、音頻、視頻等超文本的內(nèi)容。

1.認(rèn)識(shí)URL

URL(Uniform Resoure Locator)叫作統(tǒng)一資源定位符,它就是我們平時(shí)所俗稱的網(wǎng)址,一般由下面這幾部分組成:協(xié)議方案名、登錄信息、服務(wù)器地址、服務(wù)器端口號(hào)、帶層次的文件路徑、查詢字符串、片段標(biāo)識(shí)符。

HTTP協(xié)議介紹

  1. 協(xié)議方案名:表示采用的是什么協(xié)議。
  2. 登錄信息:表示用戶的登錄信息,這個(gè)字段一般可以不需要我們自己輸入,現(xiàn)在的網(wǎng)頁一般只需要我們輸入賬號(hào)密碼,或者快捷登錄,瀏覽器客戶端拿到我們的登錄信息之后自動(dòng)幫我們做轉(zhuǎn)換并填充URL中的這一個(gè)字段,所以這一字段一般是省略的,不需要我們顯式地去寫在URL上。
  3. 服務(wù)器地址:這個(gè)字段是必須有的,它表示的是服務(wù)器的IP地址,雖然我們平時(shí)瀏覽的網(wǎng)頁看到的這一字段并不是IP地址的形式,但這是因?yàn)榫W(wǎng)頁用域名代替了它的IP地址,域名方便記憶,瀏覽器客戶端自動(dòng)會(huì)幫我們將域名轉(zhuǎn)換成對(duì)應(yīng)的IP地址。
  4. 服務(wù)器端口號(hào):服務(wù)器地址后冒號(hào)緊跟的是服務(wù)器端口號(hào)。使用網(wǎng)絡(luò)服務(wù)必須有IP地址和端口號(hào),因?yàn)榫W(wǎng)絡(luò)通信的本質(zhì)就是套接字通信。一般網(wǎng)頁的URL我們是看不到端口號(hào)的,原因是使用確定協(xié)議的時(shí)候,端口號(hào)是缺省的,雖然URL上沒有顯示出來,但瀏覽器客戶端在發(fā)起網(wǎng)絡(luò)請(qǐng)求的時(shí)候會(huì)自動(dòng)幫我們添加上缺省的端口號(hào)。特定的眾所周知的服務(wù),它的端口號(hào)必須是確定的比如HTTP服務(wù)的端口號(hào)是80,HTTPS服務(wù)的端口是443。
  5. 帶層次的文件路徑:表示的是服務(wù)器上要返回給客戶端的資源的路徑,比如服務(wù)器要返回網(wǎng)頁文件給瀏覽器,這里就要填上該網(wǎng)頁文件在服務(wù)器上對(duì)應(yīng)的路徑。
  6. 查詢字符串和片段標(biāo)識(shí)符:這兩個(gè)都是在問號(hào)后面的,在URL中問號(hào)后面的代表的是一些參數(shù),參數(shù)的類型非常多樣。

urlencode和urldecode

在URL中像/、?、:等這樣的字符是有特殊含義的,因此這些字符不能隨意地出現(xiàn),如果我們的參數(shù)中出現(xiàn)了這些字符,就必須對(duì)其進(jìn)行轉(zhuǎn)義。urlencode就可以對(duì)URL進(jìn)行編碼,將特殊含義的字符進(jìn)行轉(zhuǎn)義。urldecode可以對(duì)URL進(jìn)行解碼。轉(zhuǎn)義的規(guī)則是:將需要轉(zhuǎn)碼的字符轉(zhuǎn)為16進(jìn)制,然后從右到左,取4位(不足4位直接處理),每2位做一位,前面加上%,編碼成%XY格式。

比如我們?cè)诎俣葹g覽器搜索關(guān)鍵詞C++和關(guān)鍵詞CPP,復(fù)制出來它們的URL進(jìn)行對(duì)比可以發(fā)現(xiàn):

在它們的URL中都有一個(gè)wd字段,wd是word的簡寫,代表的就是我們搜索的關(guān)鍵詞,當(dāng)關(guān)鍵詞是C++的時(shí)候,由于加號(hào)字符在URL中是有特殊含義的,所以它被轉(zhuǎn)義了,當(dāng)關(guān)鍵詞是CPP的時(shí)候就沒有被轉(zhuǎn)義。

HTTP協(xié)議介紹

二、HTTP的協(xié)議格式

1.HTTP協(xié)議的請(qǐng)求格式

HTTP是基于行格式的一套協(xié)議,第一個(gè)部分也是第一行,叫作請(qǐng)求行,包括三個(gè)字段,每個(gè)字段以空格分開,分別是請(qǐng)求方法、URL和HTTP版本,請(qǐng)求方法常見的是GET方法和POST方法,URL這里一般是去掉域名和端口號(hào)的URL,最后請(qǐng)求行以\r\n結(jié)尾。

第二部分由很多行構(gòu)成,叫作HTTP的請(qǐng)求報(bào)頭,這里面放的都是請(qǐng)求報(bào)頭的屬性。這些屬性都是key: value格式的,前面是key值,key值后面緊跟一個(gè)冒號(hào),冒號(hào)后跟一個(gè)空格,空格后跟value值。

第三部分的內(nèi)容只有\r\n,它其實(shí)是一個(gè)空行,這行其實(shí)起到的是類似于分隔符的作用,在別人解析HTTP請(qǐng)求的時(shí)候,只要讀到了這個(gè)空行,就代表讀取完了HTTP請(qǐng)求前半部分的請(qǐng)求行和報(bào)頭數(shù)據(jù)。

第四部分是在空行以后,代表的是有效載荷。也叫作請(qǐng)求正文,這部分的內(nèi)容一般比如包括用戶的登錄賬號(hào)和密碼,用戶的個(gè)人信息,音頻資源、視頻資源等等。

HTTP協(xié)議介紹

我們可以用代碼演示一下HTTP協(xié)議的請(qǐng)求報(bào)文,我們寫一個(gè)TCP服務(wù)器,讓瀏覽器作為客戶端以HTTP協(xié)議請(qǐng)求服務(wù)端,服務(wù)端讀取客戶端發(fā)送過來的信息并把它打印出來即可。

#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

using namespace std;

class TcpServer;

struct ThreadData
{
    int _sock;
    TcpServer *_server;

    ThreadData(int sock, TcpServer *server)
        : _sock(sock), _server(server)
    {
    }
};

class TcpServer
{
public:
    TcpServer(uint16_t port, const string &ip = "")
        : _listen_socket(0), _port(port), _ip(ip)
    {
    }

    ~TcpServer()
    {
    }

public:
    void init()
    {
        // 1.創(chuàng)建套接字
        _listen_socket = socket(AF_INET, SOCK_STREAM, 0);
        if (_listen_socket < 0)
        {
            cerr << "socket error" << endl;
            exit(1);
        }
        cout << "socket success" << endl;

        // 2.bind
        // 2.1填充網(wǎng)絡(luò)信息
        sockaddr_in local;
        memset(&local, 0, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = _ip.empty() ? INADDR_ANY : inet_addr(_ip.c_str());
        // 2.2bind網(wǎng)絡(luò)信息
        if (bind(_listen_socket, (const sockaddr *)&local, sizeof(local)) < 0)
        {
            cerr << "bind error" << endl;
            exit(2);
        }
        cout << "bind success" << endl;

        // 3.listen
        if (listen(_listen_socket, 5) < 0)
        {
            cerr << "listen error" << endl;
            exit(3);
        }
        cout << "listen success" << endl;
    }

    void start()
    {
        while (true)
        {
            // 1.accept
            sockaddr_in peer;
            memset(&peer, 0, sizeof(peer));
            socklen_t peer_len = sizeof(peer);
            int accept_socket = accept(_listen_socket, (sockaddr *)&peer, &peer_len);
            if (accept_socket < 0)
            {
                continue;
            }

            // 獲取連接成功,開始提供服務(wù)
            // 創(chuàng)建多線程,主線程負(fù)責(zé)accept獲取連接,新線程負(fù)責(zé)提供服務(wù)
            pthread_t tid;
            ThreadData *td = new ThreadData(accept_socket, this);
            pthread_create(&tid, nullptr, httpServer, (void *)td);
        }
    }

public:
    static void *httpServer(void *args)
    {
        ThreadData *td = (ThreadData *)args;
        while (true)
        {
            char buffer[10240];
            ssize_t readRes = read(td->_sock, buffer, sizeof(buffer) - 1);
            if (readRes > 0)
            {
                buffer[readRes] = '\0';
                // 將請(qǐng)求打印出來
                cout << buffer << endl;
            }
        }
    }

private:
    int _listen_socket;
    uint16_t _port;
    string _ip;
};

// ./server port ip
int main(int argc, char *argv[])
{
    // 命令行參數(shù)的格式輸入錯(cuò)誤
    if (argc != 2 && argc != 3)
    {
        cerr << "argc error,usage:./server port ip";
        exit(4);
    }
    uint16_t server_port = (uint16_t)atoi(argv[1]);
    string server_ip = "";
    if (argc == 3)
    {
        server_ip = argv[2];
    }

    TcpServer svr(server_port, server_ip);
    svr.init();
    svr.start();

    return 0;
}

運(yùn)行代碼啟動(dòng)服務(wù)器以后,我們讓瀏覽器以HTTP協(xié)議請(qǐng)求我們的服務(wù)器,就可以看到它發(fā)送過來的請(qǐng)求報(bào)文:

我們可以看到它是以Get方式發(fā)起請(qǐng)求的,HTTP版本是HTTP1.1,Host指的是服務(wù)器主機(jī)的地址和端口號(hào),Connection指的是請(qǐng)求是所采用的連接方式,
HTTP協(xié)議介紹

2.HTTP協(xié)議的響應(yīng)格式

HTTP的響應(yīng)格式也是以行為單位的,并且相應(yīng)格式也是包含四個(gè)部分:

第一部分也是第一行,叫作狀態(tài)碼字段,它用來描述這一次HTTP響應(yīng)的狀態(tài)是什么,這一行的具體內(nèi)容首先是HTTP協(xié)議的版本,然后緊跟一個(gè)空格,空格后面是狀態(tài)碼,狀態(tài)碼后面緊跟一個(gè)空格,空格后面是狀態(tài)碼描述,描述該狀態(tài)碼代表什么含義。這里的HTTP協(xié)議的版本和請(qǐng)求格式中的HTTP協(xié)議版本不一定一樣,舉個(gè)例子,如果客戶端是老的客戶端,但我們服務(wù)器更新了內(nèi)容,我們需要保證的是如果客戶端沒有更新,依然能正常使用但是不能看到新的內(nèi)容,只有更新了客戶端才能看到新的內(nèi)容。這種操作其實(shí)就是在版本號(hào)這里做判斷,如果客戶端發(fā)來的請(qǐng)求中,版本號(hào)是老的版本號(hào),我們就提供對(duì)應(yīng)老版本號(hào)的服務(wù)給它,如果版本號(hào)是新的,我們就提供新版本好的服務(wù)給它。

第二部分也是由很多行構(gòu)成,叫作HTTP的響應(yīng)報(bào)頭,這里和請(qǐng)求格式中的請(qǐng)求報(bào)頭類似,放的都是響應(yīng)報(bào)頭的屬性,這些屬性都是key: value格式的,前面是key值,key值后面緊跟一個(gè)冒號(hào),冒號(hào)后跟一個(gè)空格,空格后跟value值。

第三部分與HTTP協(xié)議的請(qǐng)求格式一樣,也是空行,起到分隔符的作用。

第四部分也是有效載荷,也叫作響應(yīng)正文,這里的響應(yīng)正文對(duì)應(yīng)的是URL中請(qǐng)求的資源路徑下的資源,比如html網(wǎng)頁文件,圖片文件,音視頻文件等。

HTTP協(xié)議介紹

我們可以再在上面的代碼基礎(chǔ)上增加響應(yīng)代碼,首先我們不弄特別負(fù)責(zé)的響應(yīng),做一個(gè)簡單的響應(yīng)報(bào)文演示一下即可:

static void *httpServer(void *args)
{
    ThreadData *td = (ThreadData *)args;
    while (true)
    {
        char buffer[10240];
        ssize_t readRes = read(td->_sock, buffer, sizeof(buffer) - 1);
        if (readRes > 0)
        {
            buffer[readRes] = '\0';
            // 將請(qǐng)求打印出來
            cout << buffer << endl;
        }

        // 開始響應(yīng)回給客戶端
        // 添加狀態(tài)碼行
        string response_package = "HTTP/1.0 200 OK\r\n";
        // 添加空行
        response_package += "\r\n";
        // 添加響應(yīng)正文
        response_package += "hello world, test for http";

        // 將響應(yīng)發(fā)回給客戶端
        send(td->_sock, response_package.c_str(), response_package.size(), 0);
    }
}

運(yùn)行代碼啟動(dòng)服務(wù)器以后,我們用兩種方法來查看服務(wù)端發(fā)送回來的響應(yīng):

第一種是采用telnet工具發(fā)起http的請(qǐng)求,然后獲得響應(yīng)正文:

  1. 輸入指令telnet IP 端口號(hào)
  2. 輸入ctrl+]
  3. 再按一次回車
  4. 輸入get / http/1.0發(fā)起http的get請(qǐng)求

HTTP協(xié)議介紹

第二種方法是采用瀏覽器來訪問我們的服務(wù)器,讓瀏覽器作為客戶端發(fā)起HTTP請(qǐng)求,瀏覽器來接收HTTP響應(yīng)正文:

HTTP協(xié)議介紹

HTTP是如何保證自己的報(bào)頭和有效載荷被全部讀取的呢?

  1. 要想讀取到完整的報(bào)頭,只需要按行讀取,直到讀取到空行為止即可。
  2. 要想讀取到完整的有效載荷,就需要用到報(bào)頭屬性中的正文長度,根據(jù)正文長度來讀取。

三、利用HTTP協(xié)議返回網(wǎng)頁

我們寫一個(gè)簡單的代碼來演示一下如何將一個(gè)網(wǎng)頁信息給客戶端返回回去,上面我們演示的代碼都是在響應(yīng)報(bào)文中添加字符串作為響應(yīng),所以客戶端訪問服務(wù)端也能看到對(duì)應(yīng)的字符串。那么我們可以利用這個(gè)思路,將網(wǎng)頁的html文件用字符串提取出來,然后將整個(gè)html的文件內(nèi)容以字符串的形式響應(yīng)回去,這樣客戶端就能獲取到我們的網(wǎng)頁資源了。

1.getPath函數(shù)

客戶端給服務(wù)器發(fā)送過來的請(qǐng)求中,在請(qǐng)求的第一行就包含了資源路徑,我們可以從客戶端的請(qǐng)求中提取出資源路徑。

由于HTTP協(xié)議請(qǐng)求格式是以\r\n 作為分隔符的,那么我們查找第一個(gè)\r\n分隔符就一定能提取到第一行內(nèi)容。第一行內(nèi)容是形如 GET /a/b.html HTTP/1.0\r\n這樣的格式,資源路徑在第二部分,所以我們先正向查找第一個(gè)空格的位置,再逆向查找最后一個(gè)空格的位置,兩個(gè)空格之間的子串就是資源路徑。

但是我們還需要對(duì)提取出來的資源路徑做判斷,如果提取上來的web根目錄,我們就在資源路徑上添加首頁文件再返回。

// GET /a/b.html HTTP/1.0\r\n
string getPath(const string &request)
{
    // 查找第一個(gè)\r\n,就能查找到第一行
    size_t pos = request.find(CRLF);
    if (pos == string::npos)
    {
        return "";
    }

    // 截取第一行
    string line = request.substr(0, pos);
    // 在第一行中查找第一個(gè)空格
    size_t first = line.find(SPACE);
    if (first == string::npos)
    {
        return "";
    }
    // 在第一行中查找最后一個(gè)空格
    size_t second = line.rfind(SPACE);
    if (second == string::npos)
    {
        return "";
    }

    // 截取路徑
    string path = line.substr(first + SPACE_LEN, second - (first + SPACE_LEN));
    cout << "path: " << path << endl;
    // 如果是web根目錄,則加上首頁路徑
    if (path.size() == 1 && path[0] == '/')
    {
        cout << "web根目錄" << endl;
        path += "index.html";
    }

    return path;
}

2.readFile函數(shù)

提取到資源路徑之后,我們需要到對(duì)應(yīng)的路徑下去讀取文件內(nèi)容,再將文件內(nèi)容以字符串的形式返回。

string readFile(const string &path)
{
    // 打開文件
    ifstream in(path);
    if (!in.is_open())
    {
        return "open file error";
    }

    // 按行讀取文件
    string content;
    string line;
    while (getline(in, line))
    {
        content += line;
    }

    // 關(guān)閉文件
    in.close();
    return content;
}

3.回調(diào)函數(shù)

static void *httpServer(void *args)
{
    ThreadData *td = (ThreadData *)args;
    while (true)
    {
        char buffer[10240];
        string request_package;
        ssize_t readRes = read(td->_sock, buffer, sizeof(buffer) - 1);
        if (readRes > 0)
        {
            buffer[readRes] = '\0';
            request_package = buffer;
            // 將請(qǐng)求打印出來
            cout << buffer << endl;
        }

        // 提取請(qǐng)求中的資源路徑
        if (request_package.empty())
        {
            continue;
        }
        string recourse_path = td->_server->getPath(request_package);

        string file_path = "./wwwroot";
        file_path += recourse_path;

        cout << file_path << endl;

        // 讀取資源路徑下的文件
        string html = td->_server->readFile(file_path);

        // 開始響應(yīng)回給客戶端
        // 添加狀態(tài)碼行
        string response_package = "HTTP/1.1 200 OK\r\n";
        response_package += "Content-Type: text/html\r\n";
        // 添加空行
        response_package += "\r\n";
        // 添加響應(yīng)正文
        response_package += html;

        // 將響應(yīng)發(fā)回給客戶端
        send(td->_sock, response_package.c_str(), response_package.size(), 0);
    }
}

四、HTTP協(xié)議的請(qǐng)求方法

我們利用網(wǎng)絡(luò)上網(wǎng)的行為可以分為兩種:

  1. 把遠(yuǎn)端的資源拿到本地,比如我們上面演示的獲取網(wǎng)頁資源、獲取圖片資源等。
  2. 把我們的屬性字段提交到遠(yuǎn)端,比如把我們的搜索關(guān)鍵字提交到遠(yuǎn)端,把我們的登錄信息提交到遠(yuǎn)端。

網(wǎng)站一般被分為靜態(tài)網(wǎng)站和動(dòng)態(tài)網(wǎng)站,靜態(tài)網(wǎng)站就是只能把遠(yuǎn)端的東西拿到本地,不能提交資源到遠(yuǎn)端,沒有交互式的網(wǎng)站;相反的,動(dòng)態(tài)網(wǎng)站就是既能把遠(yuǎn)端的東西拿到本地,也可以提交資源到遠(yuǎn)端,就是具有交互式的網(wǎng)站,比如我們寫博客,CSDN官網(wǎng)就是一個(gè)交互式的動(dòng)態(tài)網(wǎng)站。

將遠(yuǎn)端資源拿到本地可以采用GET方法,將本地資源提交到遠(yuǎn)端可以采用GET方法或者POST方法。

GET方法和POST方法有什么區(qū)別?

  1. GET方法是通過URL進(jìn)行傳參的,客戶端的參數(shù)會(huì)以明文的形式顯示在URL中。
  2. POST方法是通過正文進(jìn)行傳參的,客戶端的參數(shù)不會(huì)顯示在URL中,但是會(huì)出現(xiàn)在請(qǐng)求正文中。
  3. 所以GET方法是不私密的,它也是不安全的,比如我們?cè)诰W(wǎng)頁輸入賬號(hào)密碼的時(shí)候,這些會(huì)作為參數(shù)顯示在URL中。
  4. POST方法因?yàn)槭峭ㄟ^正文傳參,所以相對(duì)比較私密,但它也是不安全的,比如我們?cè)诰W(wǎng)頁輸入的賬號(hào)密碼,雖然URL中不會(huì)顯示出來,但如果別人用一些抓包工具抓取到了你的請(qǐng)求正文,也是可以輕而易舉地獲取你的賬戶信息的。

GET方法和POST方法是HTTP協(xié)議最常用的兩種方法,除了GET方法和POST方法之外,還有一些不太常用的方法,下面表格是對(duì)所有方法的匯總介紹:

其中有一些方法通常是會(huì)被服務(wù)器禁止掉的,比如DELETE方法,必須被禁止,否則別人通過客戶端發(fā)起一個(gè)DELETE請(qǐng)求就可以隨意刪除我們服務(wù)端的文件,是非常危險(xiǎn)的。

方法 說明 支持的HTTP協(xié)議版本
GET 獲取資源 1.0、1.1
POST 傳輸實(shí)體主體 1.0、1.1
PUT 傳輸文件 1.0、1.1
HEAD 獲取報(bào)文首部 1.0、1.1
DELETE 刪除文件 1.0、1.1
OPTIONS 詢問支持的方法 1.1
TRACE 追蹤路徑 1.1
CONNECT 要求用隧道協(xié)議連接代理 1.1
LINK 建立和資源之間的聯(lián)系 1.0
UNLINK 斷開連接關(guān)系 1.0

五、HTTP的狀態(tài)碼

HTTP協(xié)議的狀態(tài)碼有五類,分別以數(shù)字1、2、3、4、5開頭,每一類都有其特殊的含義:

  1. 1XX:以數(shù)字1開頭的這一類狀態(tài)碼是信息性狀態(tài)碼,表示當(dāng)前服務(wù)器正在處理接收的請(qǐng)求,所以如果等待時(shí)間比較長的話,服務(wù)器可以響應(yīng)這一類狀態(tài)碼表示請(qǐng)求正在處理,耐心等待。
  2. 2XX:以數(shù)字2開頭的這一類狀態(tài)碼是成功狀態(tài)碼,表示當(dāng)前服務(wù)器已經(jīng)正常處理完畢客戶端的請(qǐng)求。
  3. 3XX:以數(shù)字3開頭的這一類狀態(tài)碼是重定向狀態(tài)碼,表示需要附加操作以完成請(qǐng)求。目前瀏覽器主流接受的重定向狀態(tài)碼就只有兩個(gè),一個(gè)是301另一個(gè)是302。301是永久重定向,它的應(yīng)用場景一般是某些網(wǎng)站因?yàn)橛蛎牧?,為了讓老用戶從老域名也能訪問到新網(wǎng)站,就使用永久重定向,當(dāng)別人訪問老域名時(shí)會(huì)自動(dòng)跳轉(zhuǎn)到新域名。302是臨時(shí)重定向,它的應(yīng)用場景一般是某些網(wǎng)站要更新資源時(shí),為了不讓網(wǎng)站停機(jī),會(huì)創(chuàng)建一個(gè)臨時(shí)重定向讓用戶訪問原來的資源,當(dāng)新資源更新好了以后再撤銷這個(gè)臨時(shí)重定向。
  4. 4XX:以數(shù)字4開頭的這一類狀態(tài)碼是客戶端錯(cuò)誤狀態(tài)碼,表示服務(wù)器無法處理請(qǐng)求。比如我們經(jīng)常見到的404狀態(tài)碼。
  5. 5XX:以數(shù)字5開頭的這一類狀態(tài)碼是服務(wù)器錯(cuò)誤狀態(tài)碼,表示服務(wù)器處理請(qǐng)求時(shí)服務(wù)器出錯(cuò)了。

六、HTTP常見的報(bào)頭屬性

  1. Content-Type:數(shù)據(jù)類型(text/html等)
  2. Content-Length:Body的長度
  3. Host:客戶端告知服務(wù)器, 所請(qǐng)求的資源是在哪個(gè)主機(jī)的哪個(gè)端口上
  4. User-Agent:聲明用戶的操作系統(tǒng)和瀏覽器版本信息
  5. referer:當(dāng)前頁面是從哪個(gè)頁面跳轉(zhuǎn)過來的
  6. location:搭配3xx狀態(tài)碼使用, 告訴客戶端接下來要去哪里訪問
  7. Cookie:用于在客戶端存儲(chǔ)少量信息. 通常用于實(shí)現(xiàn)會(huì)話(session)的功能

七、cookie和session

HTTP協(xié)議有一個(gè)特點(diǎn)就是,用戶的訪問行為,HTTP協(xié)議不會(huì)記錄。但是我們會(huì)發(fā)現(xiàn),我們?cè)谑褂脼g覽器上網(wǎng)的時(shí)候,瀏覽器是會(huì)有記錄我們的訪問行為的,再比如說我們用一些網(wǎng)站在登錄的時(shí)候,第一次登錄需要我們輸入賬號(hào)密碼,但是第二次登錄就不需要了。

這種功能是通過cookie來實(shí)現(xiàn)的,它的原理是:當(dāng)我們用瀏覽器作為客戶端訪問服務(wù)器的時(shí)候,如果需要登錄,第一次登錄我們需要在客戶端輸入用戶名和密碼,客戶端再將用戶名和密碼發(fā)送回給服務(wù)端,服務(wù)端拿到用戶名和密碼后去數(shù)據(jù)庫中比對(duì),如果查找到了該用戶且密碼正確就可以成功登錄,成功登錄以后服務(wù)端會(huì)將成功登錄的信息響應(yīng)回給客戶端,客戶端拿到這些信息就會(huì)生成對(duì)應(yīng)的cookie文件,該文件中就保存著用戶名和密碼。在下一次客戶端發(fā)起HTTP請(qǐng)求的時(shí)候,它會(huì)自動(dòng)攜帶cookie文件的內(nèi)容,也就不再需要我們輸入用戶名和密碼了。

但是cookie策略是有安全隱患的,如果cookie文件保存了過于私密的信息,一旦cookie文件泄露出去,可能會(huì)對(duì)我們的數(shù)據(jù)安全或者財(cái)產(chǎn)安全產(chǎn)生很大影響。所以現(xiàn)在主流的會(huì)話保持策略是cookie+session方案。

cookie+session的方案是當(dāng)用戶第一次登錄輸入用戶名和密碼時(shí),服務(wù)端會(huì)幫我們生成一份session文件用來保存用戶的私密信息,并且會(huì)為這個(gè)session文件生成唯一的文件名,也就相當(dāng)于生成了一份唯一的文件編號(hào)。然后服務(wù)端再將成功登錄的信息響應(yīng)回給客戶端,并且會(huì)將session文件的對(duì)應(yīng)編號(hào)值發(fā)送給客戶端,客戶端收到之后就會(huì)生成cookie,此時(shí)客戶端的cookie文件就不再保存用戶的私密信息了,而是將session文件的編號(hào)值保存在cookie文件中。下一次訪問服務(wù)器的時(shí)候,客戶端發(fā)送cookie文件中的編號(hào)值即可。也就是說,這種方案是將原來保存在客戶端本地的用戶私密信息保存到了遠(yuǎn)端的服務(wù)器上。

八、Connection字段

在HTTP協(xié)議的請(qǐng)求和響應(yīng)報(bào)文中,有一個(gè)Connection字段,它表示HTTP協(xié)議是長鏈接還是短鏈接,在HTTP/1.0版本中是基于短鏈接的,所謂的短鏈接(closed)就是客戶端發(fā)起一次請(qǐng)求,服務(wù)端響應(yīng)之后就關(guān)閉鏈接了,短鏈接一次只處理一個(gè)HTTP請(qǐng)求。我們?nèi)粘?吹降木W(wǎng)頁,它可能這一張網(wǎng)頁就發(fā)起了幾十次上百次的HTTP請(qǐng)求,HTTP協(xié)議底層采用的就是TCP協(xié)議,每一次鏈接都需要在底層經(jīng)歷三次握手,斷開鏈接都需要經(jīng)歷四次揮手,如果現(xiàn)在主流的網(wǎng)站還是采用短鏈接的話,一個(gè)HTTP請(qǐng)求處理完之后就斷開,下一個(gè)HTTP請(qǐng)求來的時(shí)候再建立鏈接,那一張網(wǎng)頁加載出來可能要幾十次上百次的發(fā)起HTTP請(qǐng)求,在底層就要經(jīng)歷很多次的三次握手和四次揮手,這樣的成本是很高的效率也是很低的。

所以短鏈接就不再適合現(xiàn)在主流的HTTP請(qǐng)求了,我們采用主流的長鏈接。采用長鏈接的方案,客戶端和服務(wù)端在建立網(wǎng)絡(luò)連接之前先要進(jìn)行HTTP版本和連接方式協(xié)商,如果版本號(hào)一致并且Connection字段是keep-alive,代表雙方采用長鏈接的方式。雙方建立鏈接之后,服務(wù)端不會(huì)在處理完一個(gè)請(qǐng)求之后就斷開鏈接,而是接收客戶端的多次HTTP請(qǐng)求,按順序處理之后再響應(yīng)回給客戶端。當(dāng)所有的請(qǐng)求完畢時(shí)才會(huì)斷開鏈接,比如說我們?cè)诩虞d一張網(wǎng)頁時(shí),它可能會(huì)發(fā)起多次HTTP請(qǐng)求,當(dāng)一張完整的網(wǎng)頁被加載出來時(shí),雙方的鏈接才會(huì)被斷開。文章來源地址http://www.zghlxwxcb.cn/news/detail-423971.html

到了這里,關(guān)于HTTP協(xié)議介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • JavaEE & HTTP應(yīng)用層協(xié)議

    JavaEE & HTTP應(yīng)用層協(xié)議

    HTTP應(yīng)用層協(xié)議 超文本傳輸協(xié)議(Hyper Text [Transfer Protocol](https://baike.baidu.com/item/Transfer Protocol/612755?fromModule=lemma_inlink),HTTP) 是一個(gè)簡單的請(qǐng)求-響應(yīng)協(xié)議 ,它通常運(yùn)行在TCP之上。它指定了客戶端可能發(fā)送給服務(wù)器什么樣的消息以及得到什么樣的響應(yīng)。請(qǐng)求和響應(yīng)消息的頭以

    2024年02月06日
    瀏覽(24)
  • 【JavaEE】HTTP應(yīng)用層協(xié)議

    【JavaEE】HTTP應(yīng)用層協(xié)議

    HTTP應(yīng)用層協(xié)議 超文本傳輸協(xié)議(Hyper Text [Transfer Protocol](https://baike.baidu.com/item/Transfer Protocol/612755?fromModule=lemma_inlink),HTTP) 是一個(gè)簡單的請(qǐng)求-響應(yīng)協(xié)議 ,它通常運(yùn)行在TCP之上。它指定了客戶端可能發(fā)送給服務(wù)器什么樣的消息以及得到什么樣的響應(yīng)。請(qǐng)求和響應(yīng)消息的頭以

    2024年02月07日
    瀏覽(25)
  • 【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層協(xié)議 -- HTTP協(xié)議

    【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層協(xié)議 -- HTTP協(xié)議

    協(xié)議。網(wǎng)絡(luò)協(xié)議的簡稱,網(wǎng)絡(luò)協(xié)議是通信計(jì)算機(jī)雙方必須共同遵守的一組約定,比如怎么建立連接,怎么互相識(shí)別等。 為了使數(shù)據(jù)在網(wǎng)絡(luò)上能夠從源頭到達(dá)目的,網(wǎng)絡(luò)通信的參與方必須遵守相同的規(guī)則,我們稱這套相同的規(guī)則為協(xié)議(protocol),而協(xié)議最終都需要通過計(jì)算機(jī)

    2024年02月15日
    瀏覽(27)
  • 【應(yīng)用層】網(wǎng)絡(luò)基礎(chǔ) -- HTTP協(xié)議

    【應(yīng)用層】網(wǎng)絡(luò)基礎(chǔ) -- HTTP協(xié)議

    協(xié)議是一種 “約定”. socket api的接口,在讀寫數(shù)據(jù)時(shí),都是按 “字符串” 的方式來發(fā)送接收的(tcp是以字節(jié)流的方式發(fā)送的,這里便與表述使用\\\"字符串\\\") 如果我們要傳輸一些\\\"結(jié)構(gòu)化的數(shù)據(jù)\\\" 怎么辦呢? 那么我們(TCP)在收到一個(gè)報(bào)文的時(shí)候,如何保證你收到了一個(gè)完整的報(bào)文?

    2024年02月11日
    瀏覽(58)
  • 【Linux】應(yīng)用層之HTTP協(xié)議

    【Linux】應(yīng)用層之HTTP協(xié)議

    在應(yīng)用層,需要我們傳遞應(yīng)用層所需特殊的數(shù)據(jù)格式,這種數(shù)據(jù)可能是連續(xù)數(shù)據(jù),例如int類型的整形變量,也可能是string類型的字符串,也可能是多個(gè)變量構(gòu)成的結(jié)構(gòu)體,那么就意味著我們發(fā)送的數(shù)據(jù)可能是連續(xù)的,也可能是不連續(xù)的,這時(shí)為了統(tǒng)一數(shù)據(jù)的解析方法,我們對(duì)

    2024年02月12日
    瀏覽(31)
  • Linux網(wǎng)絡(luò):應(yīng)用層之HTTP協(xié)議

    Linux網(wǎng)絡(luò):應(yīng)用層之HTTP協(xié)議

    我們程序員寫的一個(gè)個(gè)解決實(shí)際問題,滿足日常需求的網(wǎng)絡(luò)程序,都是在應(yīng)用層。 協(xié)議是一種約定。網(wǎng)絡(luò)協(xié)議是計(jì)算機(jī)網(wǎng)絡(luò)中通信雙方都必須遵守的一組約定。 在網(wǎng)絡(luò)通信中,都是以 “字符串” 的方式來發(fā)送和接收數(shù)據(jù)的。 如果要發(fā)送和接收一些結(jié)構(gòu)化的數(shù)據(jù),就需要序

    2023年04月26日
    瀏覽(19)
  • 【Java】應(yīng)用層協(xié)議HTTP和HTTPS

    【Java】應(yīng)用層協(xié)議HTTP和HTTPS

    HTTP (全稱為 “超文本傳輸協(xié)議”) 是一種應(yīng)用非常廣泛的 應(yīng)用層協(xié)議. HTTP 往往是基于傳輸層的 TCP 協(xié)議實(shí)現(xiàn)的. (HTTP1.0, HTTP1.1, HTTP2.0 均為TCP, HTTP3 基于 UDP 實(shí)現(xiàn)) 當(dāng)我們?cè)跒g覽器中輸入一個(gè) 搜狗搜索的 “網(wǎng)址” (URL) 時(shí), 瀏覽器就給搜狗的服務(wù)器發(fā)送了一個(gè) HTTP 請(qǐng) 求, 搜狗的服

    2024年02月07日
    瀏覽(25)
  • 【Linux】應(yīng)用層協(xié)議:HTTP和HTTPS

    【Linux】應(yīng)用層協(xié)議:HTTP和HTTPS

    每個(gè)人都可以很喜歡每個(gè)人,但喜歡治不了病,喜歡買不了東西,喜歡不能當(dāng)飯吃,喜歡很廉價(jià)… 1.1 URL的組成 1. 在之前的文章中我們實(shí)現(xiàn)了一個(gè)網(wǎng)絡(luò)版本的計(jì)算器,在那個(gè)計(jì)算器中揉合了協(xié)議定制以及序列化反序列化的內(nèi)容,我們當(dāng)時(shí)也自己定制了一套協(xié)議標(biāo)準(zhǔn),比如請(qǐng)求

    2024年02月10日
    瀏覽(17)
  • 【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層——HTTP 協(xié)議(一)

    【計(jì)算機(jī)網(wǎng)絡(luò)】應(yīng)用層——HTTP 協(xié)議(一)

    個(gè)人主頁:兜里有顆棉花糖 歡迎 點(diǎn)贊?? 收藏? 留言? 加關(guān)注??本文由 兜里有顆棉花糖 原創(chuàng) 收錄于專欄【網(wǎng)絡(luò)編程】 本專欄旨在分享學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)的一點(diǎn)學(xué)習(xí)心得,歡迎大家在評(píng)論區(qū)交流討論?? HTTP協(xié)議全稱超文本傳輸協(xié)議,通過瀏覽器和服務(wù)器進(jìn)行數(shù)據(jù)交互,進(jìn)行

    2024年01月23日
    瀏覽(29)
  • 【應(yīng)用層協(xié)議】初始Http,fiddler的使用

    【應(yīng)用層協(xié)議】初始Http,fiddler的使用

    Http全稱是超文本傳輸協(xié)議,是一種常用的應(yīng)用層協(xié)議。它是Web的基礎(chǔ),用于在客戶端和服務(wù)器之間傳遞數(shù)據(jù)和請(qǐng)求網(wǎng)頁資源。 例如 :當(dāng)我們搜索一個(gè)網(wǎng)站時(shí),就相當(dāng)于向網(wǎng)站的服務(wù)器發(fā)送一個(gè)http請(qǐng)求,當(dāng)網(wǎng)站的服務(wù)器收到請(qǐng)求后就會(huì)進(jìn)行響應(yīng)。 HTTP 往往是基于傳輸層的 T

    2024年02月07日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包