HTML5 -- fetch 發(fā)送網絡請求

Fetch Api 概述

XMLHttpRequest 的問題:

  1. 所有的功能全部集中在同一個對象上朋譬,容易書寫出混亂不易維護的代碼。

  2. 采用傳統的事件驅動模式,無法適配新的 Promise Api。

Fetch Api 的特點

1. 并非取代 AJAX蒂破,而是對 AJAX 傳統 API 的改進。

2. 精細的功能分割:頭部信息埠居、請求信息胁孙、響應信息等均分布到不同的對象熙暴,更利于處理各種復雜的 AJAX 場景。

3. 使用 Promise APIX,更利于異步代碼的書寫。

4. Fetch Api 并非 ES6 的內容,屬于 HTML5 新增的 web api剑鞍。

Fetch Api 基本使用

使用fetch函數即可向服務器發(fā)送網絡請求。

參數

該函數有兩個參數:

  1. 必填爽醋,字符串蚁署,請求地址。

  2. 選填蚂四,對象光戈,請求配置。

請求配置對象:

1. method:字符串遂赠,請求方法久妆,默認值GET。

2. headers:對象跷睦,請求頭信息筷弦。

3. body:請求體的內容,必須匹配請求頭中的 Content-Type抑诸。

4. mode:字符串烂琴,請求模式。

  • cors:默認值蜕乡,配置為該值奸绷,會在請求頭中加入 origin 和 referer。

  • no-cors:配置為該值层玲,不會在請求頭中加入 origin 和 referer号醉,跨域的時候可能會出現問題反症。

  • same-origin:指示請求必須在同一個域中發(fā)生,如果請求其他域畔派,則會報錯铅碍。

5. credentials:如何攜帶憑據(cookie)。

  • omit:默認值父虑,不攜帶 cookie该酗。

  • same-origin:請求同源地址時攜帶 cookie。

  • include:請求任何地址都攜帶 cookie士嚎。

6. cache:配置緩存模式呜魄。

  • default:表示 fetch 請求之前將檢查下 http 的緩存。

  • no-store:表示 fetch 請求將完全忽略 http 緩存的存在莱衩,這意味著請求之前將不再檢查下 http 的緩存爵嗅,拿到響應后,它也不會更新 http 緩存笨蚁。

  • no-cache:如果存在緩存睹晒,那么 fetch 將發(fā)送一個條件查詢 request 和一個正常的 request,拿到響應后括细,它會更新 http 緩存伪很。

  • reload:表示 fetch 請求之前將忽略 http 緩存的存在,但是請求拿到響應后奋单,它將主動更新 http 緩存锉试。

  • force-cache:表示 fetch 請求不顧一切的依賴緩存,即使緩存過期了览濒,它依然從緩存中讀取呆盖,除非沒有任何緩存,那么它將發(fā)送一個正常的 request贷笛。

  • only-if-cached:表示 fetch 請求不顧一切的依賴緩存应又,即使緩存過期了,它依然從緩存中讀取乏苦,如果沒有緩存株扛,它將拋出網絡錯誤(該設置只在 mode 為 same-origin 時有效)。

返回值

fetch 函數返回一個 Promise 對象汇荐。

  • 當收到服務器的返回結果后洞就,Promise 進入 resolved 狀態(tài),狀態(tài)數據為 Response 對象拢驾。

  • 當網絡發(fā)生錯誤(或其他導致無法完成交互的錯誤)時奖磁,Promise 進入 rejected 狀態(tài)改基,狀態(tài)數據為錯誤信息繁疤。

Response 對象:

1. ok:boolean咖为,當響應消息碼在 200~299 之間時為 true,其他未 false稠腊。

2. status:number躁染,響應的狀態(tài)碼。

<button>得到數據</button>
<script>
    function getProvices() {
        const url = "";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }
        fetch(url, config).then(resp => {
            console.log(resp);
        }, err => {
            console.log(err);
        })
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

3. text():用于處理文本格式的 Ajax 響應架忌。它從響應中獲取文本流吞彤,將其讀完,然后返回一個被解決為 string 對象的 Promise叹放。

<button>得到數據</button>
<script>
    async function getProvices() {
        const url = "";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }

        try{
            const resp = await fetch(url, config);
            const pro = await resp.text();
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

4. blob():用于處理二進制文件格式饰恕,(比如圖片或電子表格)的 Ajax 響應。它讀取文件的原始數據井仰,一旦讀取完整個文件埋嵌,就返回一個被解決為 blob 對象的 Promise。

5. json():用于處理 JSON 格式的 Ajax 的響應俱恶,它將 JSON 數據流轉換為一個被解決為 JavaScript 對象的 Promise雹嗦。

<button>得到數據</button>
<script>
    async function getProvices() {
        const url = "";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }

        try{
            const resp = await fetch(url, config);
            const pro = await resp.json();
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

6. redirect():可以用于重定向到另一個 URL。它會創(chuàng)建一個新的 Promise合是,以解決來自重定向的 URL 的響應了罪。

Request 對象

除了使用基本的 fetch 方法工坊,還可以通過創(chuàng)建一個 Request 對象來完成請求(實際上释液,fetch 的內部會幫你創(chuàng)建一個 Request 對象)。

new Request(url地址炒事,配置)
<button>得到數據</button>
<script>
    async function getProvices() {
        const url = "";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }

        const req = new Request(url, config);

        try{
            const resp = await fetch(req);
            const pro = await resp.json();
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
<button>得到數據</button>
<script>
    function getRequestInfo() {
        const url = "";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }

        const req = new Request(url, config);
        return req;
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());
            const pro = await resp.json();
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

注意點:

盡量保證每次請求都是一個新的 Request 對象荔烧。

<button>得到數據</button>
<script>
    let req;
    function getRequestInfo() {
        if(!req) {
            const url = "";
            const config = {
                method: "GET",
                // headers: {
                //     "Content-Type": "application/json",
                //     a: 1
                // }
            }

            req = new Request(url, config);
        }
        
        return req.clone(); // 克隆一個全新的 request 對象吱七,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());
            const pro = await resp.json();
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

Response 對象

  1. ok:boolean,當響應消息碼在 200~299 之間時為 true鹤竭,其他未 false踊餐。

  2. status:number,響應的狀態(tài)碼臀稚。

<button>得到數據</button>
<script>
    function getProvices() {
        const url = "https://xinxin52077.github.io/Travel/travel/dist/json/city.json";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }
        fetch(url, config).then(resp => {
            console.log(resp);
        }, err => {
            console.log(err);
        })
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

3. text():用于處理文本格式的 Ajax 響應吝岭。它從響應中獲取文本流,將其讀完吧寺,然后返回一個被解決為 string 對象的 Promise窜管。

<button>得到數據</button>
<script>
    async function getProvices() {
        const url = "";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }

        try{
            const resp = await fetch(url, config);
            const pro = await resp.text();
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

4. blob():用于處理二進制文件格式,(比如圖片或電子表格)的 Ajax 響應稚机。它讀取文件的原始數據幕帆,一旦讀取完整個文件,就返回一個被解決為 blob 對象的 Promise赖条。

5. json():用于處理 JSON 格式的 Ajax 的響應失乾,它將 JSON 數據流轉換為一個被解決為 JavaScript 對象的 Promise常熙。

<button>得到數據</button>
<script>
    async function getProvices() {
        const url = "";
        const config = {
            method: "GET",
            // headers: {
            //     "Content-Type": "application/json",
            //     a: 1
            // }
        }

        try{
            const resp = await fetch(url, config);
            const pro = await resp.json();
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

6. redirect():可以用于重定向到另一個 URL。它會創(chuàng)建一個新的 Promise碱茁,以解決來自重定向的 URL 的響應裸卫。

<button>得到數據</button>
<script>
    let req;
    function getRequestInfo() {
        if(!req) {
            const url = "";
            const config = {
                method: "GET",
                // headers: {
                //     "Content-Type": "application/json",
                //     a: 1
                // }
            }

            req = new Request(url, config);
        }
        
        return req.clone(); // 克隆一個全新的 request 對象,配置一致
    }

    async function getProvices() {
        try{
            // const resp = await fetch(getRequestInfo());

            const resp = new Response(`[
                {"id": 1, "name": "北京"},
                {"id": 2, "name": "廣東"}
            ]`, {
                ok: true,
                status: 200
            });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

Headers 對象

<button>得到數據</button>
<script>
    let req;
    function getRequestInfo() {
        if(!req) {
            const url = "";
            const config = {
                method: "GET",
                headers: {
                    a: 1
                }
            }

            req = new Request(url, config);

            console.log(req.headers);
        }
        
        return req.clone(); // 克隆一個全新的 request 對象纽竣,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

在 Request 和 Response 對象內部墓贿,會將傳遞的請求頭對象,轉換為 Headers蜓氨。

Headers 對象中的方法:

  • has(key):檢查請求頭中是否存在指定的 key 值聋袋。
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            req = new Request(url, config);

            console.log(req.headers.has("a")); // true
            console.log(req.headers.has("c")); // false
        }
        
        return req.clone(); // 克隆一個全新的 request 對象,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
  • get(key):得到請求頭中對應的 key 值穴吹。
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            req = new Request(url, config);

            console.log(req.headers.get("a")); // 1
            console.log(req.headers.get("c")); // null
        }
        
        return req.clone(); // 克隆一個全新的 request 對象舱馅,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
  • set(key, value):修改對應的鍵值對。
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            req = new Request(url, config);

            console.log(req.headers.set("a", 2)); // undefined
            console.log(req.headers.set("c", 3)); // undefined
            console.log(req.headers.get("a")); // 2
            console.log(req.headers.get("c")); // 3
        }
        
        return req.clone(); // 克隆一個全新的 request 對象刀荒,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
  • append(key, value):添加對應的鍵值對代嗤。
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            req = new Request(url, config);

            console.log(req.headers.append("a", 2)); // undefined
            console.log(req.headers.append("c", 3)); // undefined
            console.log(req.headers.get("a")); // 1,2
            console.log(req.headers.get("c")); // 3
        }
        
        return req.clone(); // 克隆一個全新的 request 對象缠借,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
  • keys():得到所有的請求頭 鍵 的集合干毅。
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            headers.append("c", 7);

            req = new Request(url, config);

            const datas = req.headers.keys();

            for(const d of datas) {
                console.log(d); // a  c
            }

        }
        
        return req.clone(); // 克隆一個全新的 request 對象,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
  • values():得到所有的請求頭 值 的集合泼返。
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            headers.append("c", 7);

            req = new Request(url, config);

            const datas = req.headers.values();

            for(const d of datas) {
                console.log(d); // 1  7
            }

        }
        
        return req.clone(); // 克隆一個全新的 request 對象硝逢,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
  • entries():得到所有的請求頭 鍵值 的集合。
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            headers.append("c", 7);

            req = new Request(url, config);

            const datas = req.headers.entries();

            for(const d of datas) {
                console.log(d); // ["a", "1"]   ["c", "7"]
            }

        }
        
        return req.clone(); // 克隆一個全新的 request 對象绅喉,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>
<button>得到數據</button>
<script>
    let req;

    function getCommonHeader() {
        return new Headers({
            a: 1
        })
    }

    function getRequestInfo() {
        if(!req) {
            const url = "";
            const headers = getCommonHeader();
            const config = {
                method: "GET",
                headers
            }

            headers.append("c", 7);

            req = new Request(url, config);

            const datas = req.headers.entries();

            for(const d of datas) {
                console.log(`key : ${d[0]}, value : ${d[1]}`); // ["a", "1"]   ["c", "7"]
            }

        }
        
        return req.clone(); // 克隆一個全新的 request 對象渠鸽,配置一致
    }

    async function getProvices() {
        try{
            const resp = await fetch(getRequestInfo());

            // const resp = new Response(`[
            //     {"id": 1, "name": "北京"},
            //     {"id": 2, "name": "廣東"}
            // ]`, {
            //     ok: true,
            //     status: 200
            // });

            const pro = await getJson(resp);
            console.log(pro);
        }catch(err) {
            console.log(err);
        }
    }

    async function getJson(resp) {
        const json = await resp.json();
        return json;
    }

    document.getElementsByTagName("button")[0].onclick = function() {
        getProvices();
    }
</script>

文件上傳

流程:

  1. 客戶端將文件數據發(fā)送給服務器。

  2. 服務器保存上傳的文件數據到服務器端柴罐。

  3. 服務器響應給客戶端一個文件訪問地址徽缚。

請求方法:POST。
請求的表單格式:multipart/form-data革屠。
請求體中必須包含一個鍵值對凿试,鍵的名稱是服務器要求的名稱,值是文件數據似芝。(鍵的名稱:表單域名稱那婉, imagefile)

HTML5中,JS仍然無法隨意的獲取文件數據党瓮,但是可以獲取到 input 中详炬,被用戶選中的文件數據。

可以利用 HTML5 提供的 FormData 構造函數來創(chuàng)建請求體寞奸。

<img src="" alt="" id="img">
<input type="file" id="input">
<button>上傳</button>

<script>
    async function upload() {
        const inp = document.getElementById("input");

        if(inp.files.length === 0) {
            alert("請選擇要上傳的文件");
        }
        const formData = new FormData(); // 構建請求體
        formData.append("imagefile", inp.files[0]);
        const url = "";
        const resp = await fetch(url, {
            method: "POST",
            body: formData // 自動修改請求頭
        })
        const result = await resp.json();
        console.log(result);
        return result;
    }

    document.getElementsByTagName("button")[0].onclick = async function() {
        const result = await upload();
        console.log(result);
        const img = document.getElementById("img");
        img.src = result.path;
    }
</script>
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末呛谜,一起剝皮案震驚了整個濱河市傲醉,隨后出現的幾起案子,更是在濱河造成了極大的恐慌呻率,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呻引,死亡現場離奇詭異礼仗,居然都是意外死亡,警方通過查閱死者的電腦和手機逻悠,發(fā)現死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門元践,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人童谒,你說我怎么就攤上這事单旁。” “怎么了饥伊?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵象浑,是天一觀的道長。 經常有香客問我琅豆,道長愉豺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任茫因,我火速辦了婚禮蚪拦,結果婚禮上,老公的妹妹穿的比我還像新娘冻押。我一直安慰自己驰贷,他們只是感情好,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布洛巢。 她就那樣靜靜地躺著括袒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稿茉。 梳的紋絲不亂的頭發(fā)上箱熬,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音狈邑,去河邊找鬼城须。 笑死,一個胖子當著我的面吹牛米苹,可吹牛的內容都是我干的糕伐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蘸嘶,長吁一口氣:“原來是場噩夢啊……” “哼良瞧!你這毒婦竟也來了陪汽?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤褥蚯,失蹤者是張志新(化名)和其女友劉穎挚冤,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體赞庶,經...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡训挡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了歧强。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澜薄。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖摊册,靈堂內的尸體忽然破棺而出肤京,到底是詐尸還是另有隱情,我是刑警寧澤茅特,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布忘分,位于F島的核電站,受9級特大地震影響白修,放射性物質發(fā)生泄漏饭庞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一熬荆、第九天 我趴在偏房一處隱蔽的房頂上張望舟山。 院中可真熱鬧,春花似錦卤恳、人聲如沸累盗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽若债。三九已至,卻和暖如春拆融,著一層夾襖步出監(jiān)牢的瞬間蠢琳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工镜豹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留傲须,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓趟脂,卻偏偏與公主長得像泰讽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容

  • ###一已卸、前端進行網絡請求的關注點 大多數情況下佛玄,在前端發(fā)起一個網絡請求我們只需關注下面幾點: 傳入基本參數(...
    宮若石閱讀 1,302評論 0 3
  • 前言 學習本系列內容需要具備一定 HTML 開發(fā)基礎,沒有基礎的朋友可以先轉至 HTML快速入門(一) 學習 本人...
    珍此良辰閱讀 21,217評論 6 21
  • 前端網絡請求的方式主要有 Ajax 累澡,jQuery封裝的 Ajax梦抢,fetch,axios愧哟、request 等開源...
    悄敲閱讀 1,715評論 0 2
  • 導讀 傳遞信息到服務器奥吩,從服務器獲取信息,是前端發(fā)展的重中之重翅雏,尤其是現在前后端分離的大前提下,前后端的數據交互是...
    Chris_dc閱讀 2,147評論 1 9
  • Fetch API XMLHttpRequest的問題 所有的功能全部集中在同一個對象上人芽,容易寫出不易維護的代碼 ...
    percykuang閱讀 338評論 0 0