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

HTTP請求的幾種方式

這篇具有很好參考價值的文章主要介紹了HTTP請求的幾種方式。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

1.HTTP請求簡介[1]

HTTP(Hypertest Transfer Protocol)是用于傳輸像HTML這樣的超文本文件的應(yīng)用層協(xié)議。它被設(shè)計用于WEB瀏覽器端和WEB服務(wù)端的交互,但也有其它用途。HTTP遵循經(jīng)典的client-server模型,客戶端發(fā)起請求嘗試建立連接,然后等待服務(wù)端的應(yīng)答。HTTP是無狀態(tài)協(xié)議,這意味著服務(wù)端在兩次請求間不會記錄任何狀態(tài)。

2.HTTP請求內(nèi)容

2.1請求URL

每個請求有一個請求URL。

2.2請求方法[2]:

HTTP定義了一系列請求方法,這些方法表明要對給定資源所做的操作。HTTP請求方法包含GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH等8種類型。

2.3應(yīng)答狀態(tài)碼[3]

HTTP應(yīng)答狀態(tài)碼表名一個HTTP請求是否成功完成。應(yīng)答狀態(tài)碼被分為5類:

信息應(yīng)答(100199)

成功應(yīng)答(200299)

重定向信息(300399)

客戶端錯誤(400499)

服務(wù)端錯誤(500599)

2.4 HTTP頭[4]

HTTP頭使得客戶端和服務(wù)端之間可以通過HTTP請求和應(yīng)答傳遞信息。HTTP頭包含大小寫敏感的名稱,后面跟一個“:”,然后是http頭的值。HTTP的值前面的空格會被忽略。

2.4.1 Authentication
  • WWW-Authenticate: 請求資源時所用的認(rèn)證方法。可為Basic、Negotiate、NTLM等[5]
  • Authorization: 包含服務(wù)端驗證用戶的憑據(jù)。
2.4.2 Cookies
  • Cookie: 包含上一次服務(wù)端發(fā)送的Set-cookie頭中的HTTP cookies。
  • Set-Cookie: 從服務(wù)端向用戶側(cè)發(fā)送Cookie。
2.4.3 CORS
  • Access-Control-Allow-Origin:表明應(yīng)答可以與哪些Origin共享。

2.5 請求體[6]

請求體(body)是Request接口的一個屬性,它是包含請求體內(nèi)容的可讀流。GET和HEAD請求不能攜帶請求體,如果攜帶請求體會返回null。

Demo1發(fā)起了一個POST類型的請求,在Chrome的開發(fā)者工具中可以看到請求URL、請求方法、應(yīng)答狀態(tài)碼、HTTP頭和請求體等信息,如圖1。

var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:8080/day05_lzs/", true);
xhttp.send("fname=Bill&lname=Gates");

Demo1. 使用XMLHttpRequest發(fā)起一個簡單的POST請求

HTTP請求的幾種方式

圖1. Chrome瀏覽器中使用XMLHttpRequest發(fā)起的一個簡單的POST請求的請求信息

3.幾種請求的方式

3.1 document類型的請求

如圖2,從Chrome瀏覽器的開發(fā)者工具可以看出,請求的類型分為Fetch/XHR、JS、CSS、Img、Media、Font、Doc、WS (WebSocket)、 Wasm (WebAssembly)、Manifest和Other(不屬于前面列出類型中的一種)。通過瀏覽器地址欄發(fā)起的請求和form表單請求的類型都是document。

HTTP請求的幾種方式

圖2. Chrome瀏覽器開發(fā)者工具中請求的幾種類型

3.1.1 通過瀏覽器地址欄發(fā)起的請求

當(dāng)我們訪問一個web頁面時,在瀏覽器地址欄輸入訪問的地址并確認(rèn)后,會發(fā)起document類型的請求,如圖3。

HTTP請求的幾種方式

圖3. 使用Chrome瀏覽器在地址欄發(fā)起的document類型的請求

3.1.2 Form請求

Demo2是一個form表單。當(dāng)form表單提交時,會發(fā)送一個document類型的請求,如圖4。

<form action="http://127.0.0.1:8080/day05_lzs">
    <fieldset>
        <legend>Personal information:</legend>
        First name:<br>
        <input type="text" name="firstname" value="Mickey">
        <br>
        Last name:<br>
        <input type="text" name="lastname" value="Mouse">
        <br><br>
        <input type="submit" value="Submit"></fieldset>
</form>

Demo2. 一個form表單的HTML代碼

HTTP請求的幾種方式

圖4. 使用Chrome瀏覽器form表單提交時發(fā)起document類型的請求

3.2 XHR請求

3.2.1 XMLHttpRequest簡介

XMLHttpRequest(XHR) 對象用于和服務(wù)端交互。它可以從URL取回數(shù)據(jù)而不用刷新整個頁面,這使得可以只更新頁面的局部而不影響整個頁面。[7]

如Demo3所示,使用XMLHttpRequest發(fā)送GET請求,在URL中添加“?fname=Bill&lname=Gates”實現(xiàn)發(fā)送信息。XMLHttpResponse 對象的 onreadystatechange 屬性中定義了請求接收到應(yīng)答是所執(zhí)行的操作。該GET請求的在瀏覽器中的請求信息如圖5所示。

//GET請求
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        console.log("請求成功回調(diào)")
    }
};

xhttp.open("GET", "http://localhost:8080/day05_lzs/?fname=Bill&lname=Gates", true);
xhttp.send();

Demo3. 使用XMLHttpRequest發(fā)送GET請求

HTTP請求的幾種方式

圖5. 使用XMLHttpRequest發(fā)送GET請求

3.2.2 使用XMLHttpRequest發(fā)送post請求的4種方式

如Demo3所示,使用XMLHttpRequest發(fā)送POST請求,發(fā)送數(shù)據(jù)的方式有4種[8]。4中POST請求在瀏覽器中的請求信息如圖6-9所示,他們具有不同的請求頭content_type,請求體的格式分為“Request Load”和“Form Data”兩種。

//POST請求,發(fā)送數(shù)據(jù)方式一
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:8080/day05_lzs/", true);
xhttp.send("fname=Bill&lname=Gates");

//POST請求,發(fā)送數(shù)據(jù)方式二
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:8080/day05_lzs/", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("fname=Bill&lname=Gates");

//POST請求,發(fā)送數(shù)據(jù)方式三
var xhttp = new XMLHttpRequest();
const formData = new FormData();
formData.append("fname", "Bill");
formData.append("lname", "Gates"); 
xhttp.open("POST", "http://localhost:8080/day05_lzs/", true);
xhttp.send(formData);

//POST請求,發(fā)送數(shù)據(jù)方式四
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:8080/day05_lzs/", true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send('{"fname":"Bill","lname":"Gates"}');

Demo3. 使用XMLHttpRequest發(fā)送POST請求時發(fā)送數(shù)據(jù)的四種方式

HTTP請求的幾種方式

圖6. 使用XMLHttpRequest發(fā)送POST請求時發(fā)送數(shù)據(jù)方式一

HTTP請求的幾種方式

圖7.使用XMLHttpRequest發(fā)送POST請求時發(fā)送數(shù)據(jù)方式二

HTTP請求的幾種方式

圖8.使用XMLHttpRequest發(fā)送POST請求時發(fā)送數(shù)據(jù)方式三

HTTP請求的幾種方式

圖9. 使用XMLHttpRequest發(fā)送POST請求時發(fā)送數(shù)據(jù)方式四

3.2.3 JQuery.AJAX()簡介[9]

AJAX 組合了XMLHttpRequest 對象、JavaScript 和 HTML DOM;XMLHttpRequest 對象用于從 web 服務(wù)器請求數(shù)據(jù),JavaScript 和 HTML DOM用于顯示或使用數(shù)據(jù)。不同的瀏覽器對于AJAX的使用方式可能有所不同,JQUERY中解決了這個問題。在JQUERY使用ajax只需一行代碼。

//方式一
$.ajax({ url: "redirectTest",method:"GET",async:true,
        success: function(){
    console.log("ajax請求成功回調(diào)")
}});

//方式二
$.get("redirectTest",function(){console.log("ajax請求成功回調(diào)")});

Demo4. JQuery中發(fā)送ajax請求的2中方式

3.2.4 AJAX請求跨域時的瀏覽器策略

為了減少跨域請求的風(fēng)險(比如csrf),瀏覽器對從腳本中發(fā)起的跨域HTTP請求有嚴(yán)格限制。比如,XMLHttpRequest和Fetch這兩個API都遵循同源策略(same-origin policy),而對form表單提交的、瀏覽器地址欄發(fā)起的、HTML重定向和JavaScript重定向(詳見3.4.2和3.4.3節(jié))等document類型的請求則沒有限制。同源策略是指,瀏覽器只能加載相同初始域名(origin domain)的應(yīng)答,如果要加載其它域名的應(yīng)答,應(yīng)答頭中必須包含必要的CORS頭,比如“Access-Control-Allow-Origin”[10]。如Demo5,由初始域名為localhost:8080向目標(biāo)域名為127.0.0.1:8080發(fā)送ajax請求時,瀏覽器會報出如圖10的“CORS error”錯誤,錯誤的詳細(xì)信息如圖11??梢酝ㄟ^在CORSFilter對請求進(jìn)行攔截(如Demo6),設(shè)置應(yīng)答頭”Access-Control-Allow-Origin:*“,再次發(fā)送跨域請求,瀏覽器不再報出”CORS error“的錯誤。

//這是localhost:8080/day05_lzs請求響應(yīng)的index.html頁面,即初始域名為localhost:8080

var xhttp = new XMLHttpRequest();
//向目標(biāo)域名127.0.0.1:8080發(fā)送跨域請求
xhttp.open("GET", "http://127.0.0.1:8080/day05_lzs/?fname=Bill&lname=Gates", true);
xhttp.send();

Demo5. 初始域名為localhost:8080,向目標(biāo)域名為127.0.0.1:8080發(fā)送ajax請求

HTTP請求的幾種方式

圖10. 跨域發(fā)送ajax請求時,瀏覽器報出“CORS error”

HTTP請求的幾種方式

圖11. 跨域發(fā)送ajax請求時,瀏覽器控制臺輸出的詳細(xì)錯誤信息

public class CORSFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //允許所有的初始域名(origin domain)加載該應(yīng)答
        rep.setHeader("Access-Control-Allow-Origin","*");
    }
}

Demo6. 設(shè)置應(yīng)答頭"Access-Control-Allow-Origin",已解決跨域問題

3.3 Fetch請求

3.3.1 Fetch簡介[11]

Fetch API提供了獲取資源的接口,它比XMLHttpRequest更強(qiáng)大和靈活。使用fetch()方法可以發(fā)起請求并獲取資源。fetch()是一個在Window和Worker的context中的全局方法,這使得可以在任何的context下使用fetch方法。fetch()方法有一個參數(shù)必須要有,需要獲取資源的路徑。它應(yīng)答一個Promise,Promise會被解析為Response。

與XMLHttpRequest屬于callback-based API不同,F(xiàn)etch是promise-based的并可以很容易地在service worker中[12][13]使用。Fetch也整合了前沿的HTTP概念,像HTTP中的CORS及其它擴(kuò)展。

一個簡單的fetch請求看起來如下圖:示例中使用了async/await?!癮sync function”聲明了一個async函數(shù),在函數(shù)體中可以使用await。async/await使得異步的、基于promise的代碼實現(xiàn)更加簡潔,避免了額外配置復(fù)雜的promise鏈[14]。

async function logJSONData() {
  const response = await fetch("http://example.com/movies.json");
  const jsonData = await response.json();
  console.log(jsonData);
}

Demo7. 發(fā)起一個簡單的fetch請求

3.3.1.1 案例一:

如Demo8,fetch()方法可以接收包含多個配置的對象作為第二個參數(shù)。mode(請求跨源模式)中可取值為 no-cors, cors, same-origin,默認(rèn)值是cors。出于安全原因,在Chromium中,no-cors曾一度只在Service Worker中可用,其余環(huán)境會直接拒絕相應(yīng)的promise[15](后來已經(jīng)重新可用[16])。credentials表示請求是否需要帶上認(rèn)證憑據(jù),可取值為omit、same-origin、include,默認(rèn)值為same-origin。

// Example POST method implementation:
async function postData(url = "", data = {}) {
  // Default options are marked with *
  const response = await fetch(url, {
    method: "POST", // *GET, POST, PUT, DELETE, etc.
    mode: "cors", // no-cors, *cors, same-origin
    cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
    credentials: "same-origin", // include, *same-origin, omit
    headers: {
      "Content-Type": "application/json",
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: "follow", // manual, *follow, error
    referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data), // body data type must match "Content-Type" header
  });
  return response.json(); // parses JSON response into native JavaScript objects
}

postData("https://example.com/answer", { answer: 42 }).then((data) => {
  console.log(data); // JSON data parsed by `data.json()` call
});

Demo8. 使用fetch()發(fā)送請求案例一

3.3.1.2 案例二:

如Demo9,使用HTML標(biāo)簽<input type="file" />、FormData()和fetch()進(jìn)行文件上傳。

async function upload(formData) {
  try {
    const response = await fetch("https://example.com/profile/avatar", {
      method: "PUT",
      body: formData,
    });
    const result = await response.json();
    console.log("Success:", result);
  } catch (error) {
    console.error("Error:", error);
  }
}

const formData = new FormData();
const fileField = document.querySelector('input[type="file"]');

formData.append("username", "abc123");
formData.append("avatar", fileField.files[0]);

upload(formData);

Demo9. 使用fetch()發(fā)送請求案例二

3.3.1.3 案例三:

與jQuery.ajax()請求不同,fetch()返回的promise,即使?fàn)顟B(tài)碼為404或500,也不會被判斷為網(wǎng)絡(luò)錯誤而被拒絕。當(dāng)網(wǎng)絡(luò)錯誤發(fā)生或CORS配置錯誤時,才會被拒絕。所以判斷fetch()是否成功包括判斷解析出的promise,判斷Reponse.ok是否為true,如Demo10。

async function fetchImage() {
  try {
    const response = await fetch("flowers.jpg");
    if (!response.ok) {
      throw new Error("Network response was not OK");
    }
    const myBlob = await response.blob();
    myImage.src = URL.createObjectURL(myBlob);
  } catch (error) {
    console.error("There has been a problem with your fetch operation:", error);
  }
}

Demo10. 使用fetch()發(fā)送請求案例三

3.3.1.4 案例四:

如Demo11,除了直接將請求路徑直接傳遞到fetch()方法之外,也可以先創(chuàng)建Request()構(gòu)造器,并將該構(gòu)造器作為fetch()方法的參數(shù)傳遞。

async function fetchImage(request) {
  try {
    const response = await fetch(request);
    if (!response.ok) {
      throw new Error("Network response was not OK");
    }
    const myBlob = await response.blob();
    myImage.src = URL.createObjectURL(myBlob);
  } catch (error) {
    console.error("Error:", error);
  }
}

const myHeaders = new Headers();

const myRequest = new Request("flowers.jpg", {
  method: "GET",
  headers: myHeaders,
  mode: "cors",
  cache: "default",
});

fetchImage(myRequest);

Demo11. 使用fetch()發(fā)送請求案例四

? fetch()與jQuery.ajax()的主要區(qū)別有以下2點(diǎn):

1)當(dāng)應(yīng)答的HTTP狀態(tài)碼為404或500時,fetch()返回的promise不會被作為HTTP錯誤而被拒絕。在服務(wù)器應(yīng)答后,當(dāng)應(yīng)答的狀態(tài)碼在200-299之間時,則reponse.ok的值為true,否則為false。promise被拒絕僅在網(wǎng)絡(luò)錯誤或CORS配置錯誤等而導(dǎo)致請求無法完成時發(fā)生。

2)除非fetch()方法中的credentials配置項配置為include,否則fetch()將:

  • 在跨域請求時不發(fā)送cookies;
  • 跨域應(yīng)答中不會設(shè)置任何cookies;
  • 從2018開始,默認(rèn)的credentials策略默認(rèn)改為same-origin。
3.3.2 Promise
3.3.2.1 Promise簡介

Promise對象代表一個異步操作的完成狀態(tài)和結(jié)果。Promise代表的完成狀態(tài)和結(jié)果可以在將來某個時間點(diǎn)用到。在Demo12中創(chuàng)建了一個簡單的Promise,這個Promise的resolve()方法的參數(shù)值被方法.then()中的成功狀態(tài)下的回調(diào)函數(shù)所用到。Promise的.then()方法有兩個參數(shù),第一個參數(shù)是成功狀態(tài)下的回調(diào)函數(shù),第二個參數(shù)是失敗狀態(tài)下的回調(diào)函數(shù),第一個參數(shù)是必須要有的。.then()方法的返回值還是一個Promise,如果.then()中回調(diào)函數(shù)的完成狀態(tài)為成功,則可以出現(xiàn)像Demo2中的Promise鏈。[17]

const myFirstPromise = new Promise((resolve, reject) => {
    resolve("Success!");
});

myFirstPromise.then((successMessage) => {
  console.log(`Yay! ${successMessage}`);
});

//輸出結(jié)果為:Yay! Success!

Demo12. 創(chuàng)建一個簡單的Promise和Promise鏈

Demo13將Promise的.then()方法中的回調(diào)函數(shù)抽取獨(dú)立的函數(shù)了。最下面是Promise鏈,它包含3個.then()調(diào)用,1個.catch()調(diào)用,最后是finally()調(diào)用。只有1個.catch()是通常的做法,將promise鏈中所有的失敗狀狀態(tài)的回調(diào)函數(shù)去掉,只需要在promise的最后添加1個.catch()即可。Promise鏈開頭創(chuàng)建Promise時的參數(shù)為函數(shù)tetheredGetNumber,函數(shù)中resolve()表示完成狀態(tài)為成功,reject()表示完成狀態(tài)為失敗??梢钥闯鯬romise代表的完成狀態(tài)和結(jié)果是不確定的。第一個.then()方法中的失敗回調(diào)函數(shù)troubleWithGetNumber是可以去掉的,因為在promise鏈最后有了.catch()方法。.catch(failureCallback)方法可以看成是.then(null,failureCallback)的簡寫。[17]

// To experiment with error handling, "threshold" values cause errors randomly
const THRESHOLD_A = 8; // can use zero 0 to guarantee error

function tetheredGetNumber(resolve, reject) {
    const randomInt = Date.now();
    const value = randomInt % 10;
    if (value < THRESHOLD_A) {
      resolve(value);
    } else {
      reject(`Too large: ${value}`);
    }
}

function determineParity(value) {
  const isOdd = value % 2 === 1;
  return { value, isOdd };
}

function troubleWithGetNumber(reason) {
  const err = new Error("Trouble getting number", { cause: reason });
  console.error(err);
  throw err;
}

function promiseGetWord(parityInfo) {
  return new Promise((resolve, reject) => {
    const { value, isOdd } = parityInfo;
    if (value >= THRESHOLD_A - 1) {
      reject(`Still too large: ${value}`);
    } else {
      parityInfo.wordEvenOdd = isOdd ? "odd" : "even";
      resolve(parityInfo);
    }
  });
}

new Promise(tetheredGetNumber)
  .then(determineParity, troubleWithGetNumber)
  .then(promiseGetWord)
  .then((info) => {
    console.log(`Got: ${info.value}, ${info.wordEvenOdd}`);
    return info;
  })
  .catch((reason) => {
    if (reason.cause) {
      console.error("Had previously handled error");
    } else {
      console.error(`Trouble with promiseGetWord(): ${reason}`);
    }
  })
  .finally((info) => console.log("All done"));

Demo13. 一個使用Promise鏈的案例

Promise鏈?zhǔn)悄Хㄒ话愕拇嬖冢琍romise鏈的傳統(tǒng)寫法是金字塔式的,看著很不優(yōu)雅。一個簡單的Promise如Demo14所示,這里不考慮Promise是如何創(chuàng)建的,所以用doSomething()表示一個promise對象。Demo14中的createAudioFileAsync()根據(jù)給定的參數(shù)記錄生成了音像文件,并且有2個回調(diào)函數(shù),1個在音像文件創(chuàng)建成功時使用,1個在音像文件創(chuàng)建失敗后使用。示例的傳統(tǒng)寫法如Demo15所示??梢钥闯?,單個.then()方法的promise寫法與傳統(tǒng)寫法差別很小,但使用2個及以上.then()方法的Promise鏈與傳統(tǒng)寫法的差異很大。

//promise調(diào)用的基本結(jié)構(gòu)
const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);

//一個promise示例
createAudioFileAsync(audioSettings).then(successCallback, failureCallback);
function successCallback(result) {
  console.log(`Audio file ready at URL: ${result}`);
}

function failureCallback(error) {
  console.error(`Error generating audio file: ${error}`);
}

Demo14 promise調(diào)用的基本結(jié)構(gòu)與示例

//傳統(tǒng)寫法
createAudioFileAsync(audioSettings, successCallback, failureCallback);

Demo15. promise調(diào)用示例(Demo14)的傳統(tǒng)寫法

在一次執(zhí)行多個異步操作,且下一個異步操作在上一個異步操作成功后被執(zhí)行,并使用上一個異步操作成功后的結(jié)果,是一個常見的需求。連續(xù)進(jìn)行幾個異步操作傳統(tǒng)的寫法是金子塔式的,如Demo16所示。你也可以使用Promise鏈來實現(xiàn)這個需求,如圖Demo17所示。使用Promise鏈?zhǔn)苟鄠€異步操作更簡潔。Demo17也可以使用箭頭函數(shù)來實現(xiàn),如Demo18。

doSomething(function (result) {
  doSomethingElse(result, function (newResult) {
    doThirdThing(newResult, function (finalResult) {
      console.log(`Got the final result: ${finalResult}`);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

Demo16. 連續(xù)多個操作的傳統(tǒng)寫法,下一個異步操作在上一個異步操作后執(zhí)行且使用上一個異步操作的結(jié)果

doSomething()
  .then(function (result) {
    return doSomethingElse(result);
  })
  .then(function (newResult) {
    return doThirdThing(newResult);
  })
  .then(function (finalResult) {
    console.log(`Got the final result: ${finalResult}`);
  })
  .catch(failureCallback);

Demo17. 使用Promise鏈實現(xiàn)連續(xù)多個操作,下一個異步操作在上一個操作后執(zhí)行且使用上一個異步操作的結(jié)果

doSomething()
  .then((result) => doSomethingElse(result))
  .then((newResult) => doThirdThing(newResult))
  .then((finalResult) => {
    console.log(`Got the final result: ${finalResult}`);
  })
  .catch(failureCallback);

Demo18. Demo17使用箭頭函數(shù)實現(xiàn)的代碼

3.3.2.2 Promise使用的常見錯誤

Promise使用的常見錯誤一是在Promise的.then()中忘記return了,這時使用使用這個.then()方法的返回值作為參數(shù)的下一個.then()方法將不能正常執(zhí)行。由于無法獲取上一個.then()方法的返回值,這個.then()方法將不會等待上一個.then()方法執(zhí)行完再執(zhí)行,兩個.then()方法的執(zhí)行時異步的,有競爭關(guān)系,如Demo19。如Demo20,如果上一個的.then()方法沒有返回值,那么下一個.then()方法將會更早被調(diào)用,這導(dǎo)致控制臺輸出的listOfIngredients總是為[]。

doSomething()
  .then((url) => {
    // 忘記return了
    fetch(url);
  })
  .then((result) => {
    // 由于上一個.then()方法沒有返回值,這個.then()不會等待上一次.then()方法執(zhí)行完再執(zhí)行,且result為undefined
  });

Demo19. Promise使用的常見錯誤.then()方法中忘記return了

const listOfIngredients = [];

doSomething()
  .then((url) => {
    // 忘記return了
    fetch(url)
      .then((res) => res.json())
      .then((data) => {
        listOfIngredients.push(data);
      });
  })
  .then(() => {
    console.log(listOfIngredients);
    // 總是[],因為上一個.then()方法沒有完成
  });

Demo20. Promise使用的常見錯誤.then()方法中忘記return了

Promise的.then()方法沒有返回值是一個常見的錯誤,除此之外還有一些其它的常見錯誤,Demo21這個案例中包含了3個常見的錯誤。第一個錯誤是Promise的.then()方法沒有返回值的錯誤,已經(jīng)介紹過。第二個錯誤是Promise的嵌套是不必要的。第三個錯誤是Promise鏈的結(jié)尾沒有加上.catch()方法。對該案例錯誤修改后的代碼如Demo22。

// 錯誤案例,命中3個錯誤

doSomething()
  .then(function (result) {
    // 1.忘記return了
    // 2.不必要的嵌套
    doSomethingElse(result).then((newResult) => doThirdThing(newResult));
  })
  .then(() => doFourthThing());
// 3.忘記加上.catch()方法

Demo21. Promise使用的常見3個錯誤

doSomething()
  .then(function (result) {
   
    return doSomethingElse(result);
  })
  //如果這個.then()方法的返回值在下一個.then()方法中沒有用到,下一個.then()方法不用寫參數(shù)
  .then((newResult) => doThirdThing(newResult))
  .then((/* 參數(shù)不用寫*/) => doFourthThing())
  .catch((error) => console.error(error));

Demo22. Demo21中常見的3個錯誤修改后的代碼

3.3.2.3 Promise中的拒絕事件(reject_event)

如果一個promise的拒絕事件沒有被任何處理程序處理,他將會冒泡到調(diào)用棧的頂部,主機(jī)需要將其拋出。在web上,當(dāng)一個promise被拒絕,有兩個事件中一個會被發(fā)送到全局范圍(通常是通過window,如果使用了webworker,則通過worker或基于worker的接口)。這2個事件是:

unhandledrejection

當(dāng)一個promise被拒絕但沒有可用的拒絕事件的處理程序時,發(fā)送該事件。

rejectionhandled

當(dāng)一個被拒絕的promise已引起unhandledrejection事件的發(fā)送,再次被拒絕時一個處理程序被附加到被拒絕的promise時發(fā)送該事件。

這兩種情況下,類型為PromiseRejectionEvent的事件都有一個promise的屬性作為成員,這個屬性表明promise已被拒絕;還包括一個reason屬性,這個屬性提供了promise被拒絕的原因。

這使得為promises提供錯誤處理稱為可能,也為你的promise管理的debug問題提供幫助。這些處理程序在每個context中是全局的,因此所有的錯誤不管源頭在哪,都會去到同樣的事件處理程序。

在Node.js中,promise拒絕的處理有些許不同。你可以通過為Node.js的unhandledRejection(注意與js中unhandledrejection事件的大小寫區(qū)別)事件添加處理程序,來捕獲未被處理的拒絕。

process.on("unhandledRejection", (reason, promise) => {
  // Add code here to examine the "promise" and "reason" values
});

Demo22. nodejs中promise拒絕的處理

對于node.js,為了阻止錯誤輸出到控制臺,你可以添加process.on監(jiān)聽器,取代瀏覽器運(yùn)行時的preventDefault() 方法。如果你添加了process.on監(jiān)聽器,但是并沒有對被拒絕的promise進(jìn)行處理,那這個被拒絕的信息將被默默忽略掉。你應(yīng)該在監(jiān)聽器中添加代碼以檢查每個被拒絕的promise并確認(rèn)是否實際上由代碼的bug引起。

3.3.2.4 Promise中的異常處理

談到Promise的異常處理,你可能會想到早期金字塔式的連續(xù)異步操作示例中的failurecallback方法,如Demo23所示。在Promise中的異常處理通常如Demo24的方式,在promise鏈的最后調(diào)用.catch()方法。當(dāng)異常發(fā)生時,瀏覽器會沿著Promise鏈從上到下查找.catch()或onrejected處理器。這很大程度上模仿了如Demo25中的同步代碼的工作方式,Demo25的代碼中使用了await/async。Promises解決了一個金字塔式調(diào)用的底層缺陷,它會捕獲所有的錯誤,包括拋出的異常和編碼錯誤。Promise的異常處理是一個異步操作必要的功能組成部分。

doSomething(function (result) {
  doSomethingElse(result, function (newResult) {
    doThirdThing(newResult, function (finalResult) {
      console.log(`Got the final result: ${finalResult}`);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

Demo23. 早期金字塔式的連續(xù)異步操作,且下一個異步操作使用上一個異步操作的結(jié)果

doSomething()
  .then((result) => doSomethingElse(result))
  .then((newResult) => doThirdThing(newResult))
  .then((finalResult) => console.log(`Got the final result: ${finalResult}`))
  .catch(failureCallback);

Demo24. Promise鏈中使用.catch()進(jìn)行異常處理

async function foo() {
  try {
    const result = await doSomething();
    const newResult = await doSomethingElse(result);
    const finalResult = await doThirdThing(newResult);
    console.log(`Got the final result: ${finalResult}`);
  } catch (error) {
    failureCallback(error);
  }
}

Demo25. Promise鏈異常處理修改為使用async/await的同步代碼的方式

3.3.2.5 Promise中的then中的組合寫法

可以通過Promise.all(), Promise.allSettled() ,Promise.any(), Promise.race()等4個組合方法并發(fā)地運(yùn)行異步操作。

Promise.all([func1(), func2(), func3()]).then(([result1, result2, result3]) => {
  // use result1, result2 and result3
});

Demo26. Promise.all()組合方法的使用

如果數(shù)組中的一個promise被拒絕,Promise.all()直接拒絕了返回的promise并終止其它操作。這會引起不可預(yù)測狀態(tài)和行為。Promise.allSettled()是另外一個組合方法,它保證了所有的操作在resolve之前全部完成。這些方法中promise的運(yùn)行是并發(fā)的,一系列的promise同時開始運(yùn)行,其中的一個promise不會等待另一個promise。promise組合序列化執(zhí)行可按照Demo27中的寫法。在Demo28中,我們遍歷了要異步執(zhí)行的函數(shù),將其組合成了promise鏈,代碼等同于Demo29。

[func1, func2, func3]
  .reduce((p, f) => p.then(f), Promise.resolve())
  .then((result3) => {
    /* use result3 */
  });

Demo27. promise組合序列化寫法一

Promise.resolve()
  .then(func1)
  .then(func2)
  .then(func3)
  .then((result3) => {
    /* use result3 */
  });

Demo28. promise組合序列化寫法二

promise組合序列化執(zhí)行也可以使用async/await來實現(xiàn),如Demo29所示。

let result;
for (const f of [func1, func2, func3]) {
  result = await f(result);
}
/* use last result (i.e. result3) */

Demo29. promise組合序列化寫法三

composeAsync()函數(shù)接受任意數(shù)量的函數(shù)作為參數(shù),并返回一個函數(shù)。這個函數(shù)接收通過管道函數(shù)傳遞的一個初始參數(shù)。管道函數(shù)是按順序執(zhí)行的。

const transformData = composeAsync(func1, func2, func3);
const result3 = transformData(data);

Demo30. composeAsync的使用案例

當(dāng)你將promise進(jìn)行序列化組合時,請先考慮其是否必要。promise并發(fā)地運(yùn)行是更高效的方式,一個promise不會阻塞另一個promise。

3.3.2.6 Promise中的執(zhí)行順序[18]

Promise的回調(diào)函數(shù)隊列和這些函數(shù)何時被調(diào)用是由promise的實現(xiàn)決定的,API的開發(fā)者和使用者均遵循下面的語義:

1.通過then()添加的回調(diào)在當(dāng)前javaScript事件循環(huán)結(jié)束后才會執(zhí)行;

2.通過then()依次添加的多個回調(diào)函數(shù)會依次執(zhí)行;

Demo30的執(zhí)行結(jié)果是確定的。即使是已經(jīng)resolved的promise的then()的回調(diào)函數(shù)也不會被同步執(zhí)行。如Demo31,then()的回調(diào)函數(shù)會被添加到microtask隊列,這些micortask在當(dāng)前事件循環(huán)結(jié)束后(創(chuàng)建microtask的函數(shù)退出),在控制被返回到事件循環(huán)之前執(zhí)行。而setTimeout()的任務(wù)被添加到task隊列,這些task在下一個事件循環(huán)開始時執(zhí)行,setTimeout()后的.then()方法會在setTimeout()任務(wù)執(zhí)行后添加到microtask隊列中。

Promise.resolve().then(() => console.log(2));
console.log(1);
// Logs: 1, 2

Demo30. promise中.then()的回調(diào)函數(shù)執(zhí)行順序案例一

const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

wait(0).then(() => console.log(4));
Promise.resolve()
  .then(() => console.log(2))
  .then(() => console.log(3));
console.log(1); // 1, 2, 3, 4

Demo31. promise中.then()的回調(diào)函數(shù)執(zhí)行順序案例二

const promise = new Promise((resolve, reject) => {
  console.log("Promise callback");
  resolve();
}).then((result) => {
  console.log("Promise callback (.then)");
});

setTimeout(() => {
  console.log("event-loop cycle: Promise (fulfilled)", promise);
}, 0);

console.log("Promise (pending)", promise);

/*Promise callback
Promise (pending) Promise {<pending>}
Promise callback (.then)
event-loop cycle: Promise (fulfilled) Promise {<fulfilled>}

Demo32. promise中.then()的回調(diào)函數(shù)執(zhí)行順序案例三

3.3.3 Fetch請求跨域時的瀏覽器策略

同jQuery.ajax()一樣,fetch請求也會有跨域問題。如Demo33,由初始域名為localhost:8080向目標(biāo)域名為127.0.0.1:8080發(fā)送fetch請求時,瀏覽器會報出如圖12的“CORS error”錯誤,錯誤的詳細(xì)信息如圖13??梢酝ㄟ^在CORSFilter對應(yīng)答進(jìn)行攔截,設(shè)置應(yīng)答頭”Access-Control-Allow-Origin:*“,再次發(fā)送跨域請求,瀏覽器不再報出”CORS error“的錯誤。

//這是localhost:8080/day05_lzs請求響應(yīng)的index.html頁面,即初始域名為localhost:8080

async function logJSONData() {
    //向目標(biāo)域名127.0.0.1:8080發(fā)送跨域請求
	const response = await fetch("http://127.0.0.1:8080/day05_lzs/?                   						fname=Bill&lname=Gates");
	const jsonData = await response.json();
	console.log(jsonData);
}

Demo33 初始域名為localhost:8080,向目標(biāo)域名為127.0.0.1:8080發(fā)送fetch請求

HTTP請求的幾種方式

圖12 跨域發(fā)送fetch請求時,瀏覽器報出“CORS error”

HTTP請求的幾種方式

圖13. 跨域發(fā)送fetch請求時,瀏覽器控制臺輸出的詳細(xì)錯誤信息

3.4 重定向[19]

3.4.1 HTTP重定向

URL重定向(URL redirection),也稱為URL forwarding,它使一個頁面、表單或網(wǎng)站擁有多個URL地址。HTTP重定向是HTTP的一種應(yīng)答類型。HTTP重定向是在瀏覽器向服務(wù)端發(fā)送請求后,當(dāng)服務(wù)端進(jìn)行重定向應(yīng)答時觸發(fā)的。重定向應(yīng)答的狀態(tài)碼以“3”開頭,應(yīng)答頭“Location”的值是要重定向到的URL。當(dāng)瀏覽器接收到重定向應(yīng)答后,會立馬加載應(yīng)答頭“Location”中的URL。如圖14,在瀏覽器地址輸入"http://localhost:8080/day05_lzs/redirectTest"并打開后,瀏覽器向服務(wù)端發(fā)送請求,服務(wù)端接收到請求后進(jìn)行了重定向應(yīng)答,狀態(tài)碼為302,應(yīng)答頭”Location“為”http://127.0.0.1:8080/day05_lzs/redirectTest2“。瀏覽器接收到重定向應(yīng)答后,會立馬加載應(yīng)答頭“Location”中的URL。瀏覽器的地址欄也變?yōu)橹囟ㄏ虻腢RL。

//路徑“redirectTest”映射到的servlet
public class RedirectTestServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.sendRedirect("http://127.0.0.1:8080/day05_lzs/redirectTest2");
    }
}

Demo34. 路徑“redirectTest”映射到的servlet

HTTP請求的幾種方式

圖14. chrome瀏覽器地址欄發(fā)起請求的HTTP重定向

在xhr/fetch請求進(jìn)行HTTP重定向時,瀏覽器的地址欄不會變?yōu)橹囟ㄏ蚝蟮腢RL。如Demo35、Demo36,當(dāng)我們點(diǎn)擊按鈕觸發(fā)sendAjax()函數(shù)后,會發(fā)起URL為“redirectTest”的XMLHttpRequest請求;服務(wù)端的應(yīng)答重定向到了“ http://127.0.0.1:8080/day05_lzs/redirectTest2”;URL為“redirectTest2”的重定向請求發(fā)起后,服務(wù)端的應(yīng)答又重定向到了“http://127.0.0.1:8080/day05_lzs/redirectTest3”。一個xhr/fetch請求的重定向請求可視為ajax/fetch請求的延續(xù)。一方面如果XMLHttpRequest設(shè)置為同步執(zhí)行,則在XMLHttpRequest請求及該請求的所有重定向請求執(zhí)行完成后,才會繼續(xù)執(zhí)行Demo35中的“window.location”代碼;這點(diǎn)在圖15的請求順序中可以看出。另一方面xhr/fetch請求不會改變?yōu)g覽器地址欄的URL,xhr/fetch請求的重定向請求也不會改變?yōu)g覽器地址欄的URL。

<!--index.html-->
<head>
	<script>
        function sendAjax(){
            var xhttp = new XMLHttpRequest();
            //將請求設(shè)置為同步
			xhttp.open("POST", "redirectTest", false);
			xhttp.send()
			window.location = "http://localhost:8080/day05_lzs/redirectTestAfter"
        }
	</script>
</head>
<body>
    <button onclick="sendAjax()">發(fā)起ajax請求</button>
</body>	

demo35. xhr請求的HTTP重定向案例前端代碼

//路徑“redirectTest”映射到的servlet
public class RedirectTestServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.sendRedirect("http://127.0.0.1:8080/day05_lzs/redirectTest2");
    }
}

//路徑“redirectTest2”映射到的servlet
public class RedirectTestServlet2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        response.sendRedirect("http://127.0.0.1:8080/day05_lzs/redirectTest3");
    }
}

Demo36. xhr請求的HTTP重定向案例后端代碼

HTTP請求的幾種方式

圖15. xhr請求的HTTP重定向案例在chrome瀏覽器開發(fā)這工具中的請求記錄

重定向分為2種類型,永久重定向和臨時重定向。永久重定向表示原始的URL不應(yīng)繼續(xù)被使用,應(yīng)使用新的URL替代。搜索引擎機(jī)器人、RSS閱讀器或其它爬蟲會更新資源中的原始URL。有時請求的資源所在的規(guī)范URL不可用,但可以通過其它的URL訪問到,此時可以使用臨時重定向。搜索引擎機(jī)器人、RSS閱讀器或其它爬蟲不會記住臨時的URL。臨時重定向也可以用于在創(chuàng)建、更新和刪除資源時,顯示臨時進(jìn)度頁面。

如表1,狀態(tài)碼301和308是永久重定向,302、303、307是臨時重定向。永久重定向為何有2個狀態(tài)碼,臨時重定向為何有3個狀態(tài)碼,它們的區(qū)別是什么?以臨時重定向的3個狀態(tài)碼為例進(jìn)行說明。在HTTP/1.0時臨時重定向只有302這一個狀態(tài)碼,http規(guī)范規(guī)定重定向時不允許改變請求方法;且當(dāng)請求方法不是GET/HEAD時,在重定向前瀏覽器需要詢問客戶是否繼續(xù),非GET/HEAD請求可能會改變請求發(fā)出時的狀態(tài)。第一條重定向不允許改變請求方法的規(guī)定,很多瀏覽器的用戶代理[20]并沒有遵守,它們將302視為303對待。為了消除302狀態(tài)碼的歧義,在HTTP/1.1將302拆分成了303和307。第二條非GET/HEAD的重定向請求需要用戶確認(rèn)的規(guī)定,瀏覽器也沒有實現(xiàn)[21]。

狀態(tài)碼 文本 http規(guī)范的要求[22] 用戶代理的實現(xiàn) 典型使用場景
301 Moved Permanently HTTP/1.0重定向時不允許改變請求方法 GET方法不變。其它方法可能會也可能不會改變?yōu)镚ET方法。 網(wǎng)站重組
308 Permanent Redirect HTTP/1.1由301拆分出來 請求方法和請求體不變。 網(wǎng)站重組,非GET方法的鏈接或操作
302 Found HTTP/1.0重定向時不允許改變請求方法 GET方法不變。其它方法可能會也可能不會改變?yōu)镚ET方法。 web頁因為不可預(yù)見的原因臨時不可用
303 See Other HTTP/1.1由302拆分出來 GET方法不變。其它方法改變?yōu)镚ET方法。 在PUT和POST方法后進(jìn)行重定向,刷新頁面不會重復(fù)觸發(fā)已執(zhí)行的操作
307 Temporary Redirect HTTP/1.1由302拆分出來 請求方法和請求體不變。 web頁因為不可預(yù)見的原因臨時不可用。在使用非GET方法時使用,比302更好

表1. http重定向的狀態(tài)碼

如圖16,瀏覽器的用戶代理會以請求頭User_Agent發(fā)送到服務(wù)端,用戶代理是一個特殊的字符串,服務(wù)端可通過該字符串解析出客戶使用的操作系統(tǒng)及版本、CPU類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等。圖中User-Agent字符串各部分的解釋如下:

Mozilla/5.0: Netscape Communications 開發(fā)了 web 瀏覽器 Mozilla。凡是基于 WebKit 的瀏覽器都將自己偽裝成了 Mozilla 5.0;

(Windows NT 10.0; Win64; x64): 操作系統(tǒng)windows 10;

AppleWebKit/537.36 (KHTML, like Gecko) : Apple 宣布發(fā)布首款他們自主開發(fā)的 web 瀏覽器:Safari。它的呈現(xiàn)引擎叫 WebKit;Apple公司擔(dān)心用戶不知道WebKit的兼容性,使用(KHTML, like Gecko)讓開發(fā)者知道WebKit像Gecko一樣,是兼容Mozilla瀏覽器的;

Chrome/95.0.4638.54: Google Chrome 瀏覽器及其版本號。Chrome以 WebKit 作為呈現(xiàn)引擎;

Safari/537.36: User-Agent中包括的信息既有 Apple WebKit 的版本,也有 Safari 的版本。

HTTP請求的幾種方式

圖16. Chrome瀏覽器中請求頭User-Agent

3.4.2 HTML重定向

HTTP重定向是最好的重定向方式,但有時你無法控制服務(wù)端。你可以通過HTML中a標(biāo)簽的href屬性來實現(xiàn)重定向。HTML重定向是document類型的請求,請求方法式GET,如圖17、18。

<a href="/day05_lzs/redirectTestAfter">重定向測試</a></br>
<a href="http://localhost:8080/day05_lzs/redirectTestAfter">重定向測試</a></br>

Demo37. HTML重定向

HTTP請求的幾種方式

圖17. HTML重定向的請求方式

HTTP請求的幾種方式

圖18. HTML重定向的請求方法

3.4.3 JavaScript重定向

JavaScript的重定向通過為“window.location”設(shè)置URL來實現(xiàn)的。 JavaScript重定向是document類型的請求,請求方法式GET,如圖19、20。

//相對URL
window.location = "/day05_lzs/redirectTestAfter"
//絕對URL
window.location= "http://localhost:8080/day05_lzs/redirectTestAfter"
//window.location.href的方式
window.location.href = "http://localhost:8080/day05_lzs/redirectTestAfter"

Demo38. JavaScript重定向

HTTP請求的幾種方式

圖19. JavaScript重定向的請求方式

HTTP請求的幾種方式

圖20. JavaScript重定向的請求方式

引用:

[1] https://developer.mozilla.org/en-US/docs/Web/HTTP

[2]https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods

[3] https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

[4] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers

[5] https://www.orcode.com/question/1049930_kae50a.html

[6]https://developer.mozilla.org/en-US/docs/Web/API/Request/body

[7] https://www.w3school.com.cn/js/js_ajax_http_send.asp

[8] https://www.cnblogs.com/oxspirt/p/13096737.html

[9] https://www.w3school.com.cn/js/js_ajax_intro.asp

[10] https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

[11] https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

[12] https://blog.csdn.net/Ed7zgeE9X/article/details/124937789

[13] https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API

[14] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

[15] https://web.dev/introduction-to-fetch/#why_is_no-cors_supported_in_service_workers_but_not_the_window

[16] https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_response_header_name

[17] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#advanced_example

[18]https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#composition

[19] https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections

[20] https://baike.baidu.com/item/用戶代理/1471005?fr=aladdin

[21] https://www.cnblogs.com/OpenCoder/p/16265950.html

[22] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html文章來源地址http://www.zghlxwxcb.cn/news/detail-478330.html

到了這里,關(guān)于HTTP請求的幾種方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • Java實現(xiàn)HTTP請求的幾種方式-CloseableHttpClient(三)

    Java實現(xiàn)HTTP請求的幾種方式-CloseableHttpClient(三)

    CloseableHttpClient是在HttpClient的基礎(chǔ)上修改更新而來的,這里還涉及到請求頭token的設(shè)置(請求驗證),利用fastjson轉(zhuǎn)換請求或返回結(jié)果字符串為json格式,當(dāng)然上面兩種方式也是可以設(shè)置請求頭token、json的,這里只在下面說明。 基于第一章的測試接口,建立以下程序 創(chuàng)建客戶端

    2023年04月20日
    瀏覽(100)
  • Java實現(xiàn)HTTP請求的幾種方式-HttpURLConnection(一)

    在實際開發(fā)過程中,我們經(jīng)常需要調(diào)用對方提供的接口或測試自己寫的接口是否合適。很多項目都會封裝規(guī)定好本身項目的接口規(guī)范,所以大多數(shù)需要去調(diào)用對方提供的接口或第三方接口(短信、天氣等)。 準(zhǔn)備兩個項目: 項目A: 服務(wù)提供者 項目B:服務(wù)消費(fèi)者 在項目A中

    2024年02月16日
    瀏覽(21)
  • http請求和響應(yīng)格式說明,http的get和post請求方式說明,http的請求體body的幾種數(shù)據(jù)格式

    http請求和響應(yīng)格式說明,http的get和post請求方式說明,http的請求體body的幾種數(shù)據(jù)格式

    一個HTTP請求報文由 請求行(request line)、請求頭部(header)、空行和請求數(shù)據(jù) 4個部分組成, 請求報文的一般格式 1、第一行必須是一個請求行(request-line),用來說明請求類型,要訪問的資源以及所使用的HTTP版本 2、緊接著是一個請求頭(header),用來說明服務(wù)器要使用的附加信息

    2024年02月02日
    瀏覽(29)
  • 【Http協(xié)議④】常見的幾種構(gòu)造http請求的方式,form表單構(gòu)造,Ajax構(gòu)造,postman構(gòu)造

    【Http協(xié)議④】常見的幾種構(gòu)造http請求的方式,form表單構(gòu)造,Ajax構(gòu)造,postman構(gòu)造

    前言: 大家好,我是 良辰丫 ,這篇文章我將協(xié)同大家一起去學(xué)習(xí)幾種構(gòu)造http請求的方式.?????? ??個人主頁:良辰針不戳 ??所屬專欄:javaEE初階 ??勵志語句:生活也許會讓我們遍體鱗傷,但最終這些傷口會成為我們一輩子的財富。 ??期待大家三連,關(guān)注,點(diǎn)贊,收藏。

    2024年02月06日
    瀏覽(25)
  • java發(fā)送http請求的幾種方式,調(diào)用第三方接口的方法:HttpUtil、HttpURLConnection等

    參考:https://blog.csdn.net/yubin1285570923/article/details/126225347 put請求 post帶請求頭 get、delete類似… 使用JDK原生提供的net,無需其他jar包,代碼如下: 需要用到commons-httpclient-3.1.jar,maven依賴如下: 看一下我實際應(yīng)用的例子 需要用到httpclient-4.5.6.jar,maven依賴如下: RestTemplate 是由

    2024年01月18日
    瀏覽(34)
  • 前端實現(xiàn)動畫的幾種方式簡介

    前端實現(xiàn)動畫的幾種方式簡介

    這里只是做簡要介紹,屬于知識的拓展。每種方案的更詳細(xì)的使用方式需要各位自行了解。 大體上技術(shù)方案分為:CSS 動畫、SVG 動畫、CSS + SVG、JS 控制的逐幀動畫、GIF 圖。 CSS 實現(xiàn)動畫有兩種方式,一種是使用 trasition ;另一種是使用 animation 。 默認(rèn)情況下,當(dāng) CSS 中的屬性值

    2024年04月22日
    瀏覽(26)
  • http的請求體body的幾種數(shù)據(jù)格式

    http的請求體body的幾種數(shù)據(jù)格式

    http的請求體body的幾種數(shù)據(jù)格式:multipart/form-data;application/x-www-from-urlencoded;raw;binary key - value 格式,主要用來上傳文件,它會將表單的數(shù)據(jù)處理成一條消息,以標(biāo)簽為單元,用分隔符分開。當(dāng)上傳的字段是文件時,會有Content-Type來說明文件類型;content-disposition,用來說明

    2024年02月08日
    瀏覽(23)
  • 接口測試-關(guān)于postman的幾種參數(shù)請求方式

    接口測試-關(guān)于postman的幾種參數(shù)請求方式

    (1)POST的數(shù)據(jù)類型 對于post請求方式,一般都是要對請求發(fā)送相應(yīng)的一些參數(shù)的,而參數(shù)的注入一般填寫在Body中。 ?如上圖所示,在Body中,有多種類型選擇: none:一般都不使用 form-data: ?對于form-data,是采用鍵值對的方式進(jìn)行存儲,即將該表單的數(shù)據(jù)組織成Key-Value形式,

    2024年02月12日
    瀏覽(37)
  • js fetch請求中斷的幾種方式

    js fetch請求中斷的幾種方式

    這是官方標(biāo)準(zhǔn)手段,真正意義的阻止請求(不支持ie) 后端接口設(shè)置的兩秒返回數(shù)據(jù) 默認(rèn)結(jié)果: 解開定時器后: 通過promise,成功用resolve返回,失敗用reject返回(瀏覽器上,請求依然會發(fā)出,并得到響應(yīng)) 第一種方法: 運(yùn)行結(jié)果: 第二種方法:

    2024年02月12日
    瀏覽(27)
  • 使用OkHttp發(fā)送POST請求的幾種方式

    本文將介紹 OkHttp 客戶端的基本用法。 主要介紹 OkHttp 3.x 版本中發(fā)送Post請求的幾種方式。 使用 FormBody.Builder 構(gòu)造基本的 RequestBody , 包含兩個參數(shù):用戶名、密碼,發(fā)送 POST請求。 如果要對請求進(jìn)行身份驗證,可以使用 Credentials.basic 構(gòu)建器向請求頭中添加憑據(jù)。 下面代碼給

    2024年02月13日
    瀏覽(23)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包