http 请求 与其同步与异步请求的通透讲解
http請求可以是基于webkit的瀏覽器或者web組件如:webview(在移動平臺,android iOS等)發送的;也可以是任何程序或者代碼段發出的;也可以這么說任何程序都可以自主發送http.
http 是超文本傳輸協議,其是基于tcp/ip協議。本質上首先我們是需要借助系統開啟socket監聽,然后使用tcp傳輸協議,傳輸數據包,將數據包憑借成http request和response,這就成了http協議。但是高級語言給我們封裝了這一層。那么我們直接使用接口,無需再去自己開發(如Java,c#, javascrpt,object c)。但是正是因為這樣,我們有時候,對http的理解就沒有那么深入了。
既然任何程序代碼段都可以開發使用http協議發送http請求,那么一般的代碼段和webkit(瀏覽器內核組件)發送http有什么區別嗎?我相信很多人回答是沒有任何區別。其實本質上沒有任何的區別,但是有限制!!! webkit可以讓我們http請求一個html頁面,但是一般的代碼段就不這么做,因為我們拿到html文件也干不了什么,又不能解析展示。
可能此時有人會反駁我,HTML本來就是瀏覽器頁面,因此瀏覽器可以或者需要請求頁面,但是html和一般http請求代碼段沒有絲毫聯系,干嘛要去請求取回http頁面呢???其實這樣理解也是對的。
既然基于webkit的組件需要拿回來html頁面,那么一般組件都會提供直接加載請求html頁面的接口,如瀏覽器 中 提供 window.location ? window.navigate ? 或者JavaScript的onload方法。在webview(移動平臺)組件提供onload(url)接口。所以我們一般在組件中開發http,一般都是http請求數據包,拿回來解析數據,并非是加載一個新的頁面。換句話說我們在組件中使用Javascript或者其他腳本語言開發http是頁面上部分的數據交互。
對于其他的程序代碼段開發http請求更都是數據的交互。
對于webkit 發送http請求有一個概念就是 異步請求和同步請求。(注意這是對于瀏覽器b/c架構才有的概念)就是瀏覽器發送http請求之后,如果數據沒有回來,那么瀏覽器一直是等待狀態,那么它什么也不能做。這就是同步請求。相反瀏覽器發送數據請求之后,其還能做其他的事情,只有當數據回來了再去加載數據,這是異步請求。對于瀏覽器加載一個新的頁面,那么同步與異步沒有什么意義了,也就是說同步與異步是針對請求頁面部分數據而言的。你想想要是瀏覽器去加載一個新的頁面,還要請求,可能新頁面回來了,用戶可能還在操作其他的,那么突然加載新的頁面,感覺很不友好。
瀏覽器的異步請求(注意再強調一遍只有瀏覽器才有的這個概念)有一個名稱就是ajax asynchronized javascript and xml。就是腳本Javascript 同過創建 xmlhttpRequest 對象調用瀏覽器中的xmlhttpRequest 代理對象(現在一般所有的瀏覽器內核都集成了這個代理)
原理:瀏覽器發出的異步請求交給代理對象,瀏覽器就不管了,代理將數據請求發出,然后等待相應回來,再將數據包交給瀏覽器解析。
web 頁面通過js發送http請求代碼:
這是 js 獲取 自己的http 對象 get請求
這是 js 獲取 自己的http 對象 post請求
var http = require('http'); var qs = require('querystring'); var post_data = { a: 123, time: new Date().getTime()};//這是需要提交的數據 var content = qs.stringify(post_data); var options = { hostname: '127.0.0.1', port: 10086, path: '/pay/pay_callback', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' } }; var req = http.request(options, function (res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); }); }); req.on('error', function (e) { console.log('problem with request: ' + e.message); }); // write data to request body req.write(content); req.end();
ajax請求: function createXMLHttpRequest() { var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); if (xmlHttp.overrideMimeType) xmlHttp.overrideMimeType('text/xml'); } else if (window.ActiveXObject) { try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { } } } return xmlHttp;
xmlHttp = createXMLHttpRequest(); var url = "getfiledetail.jsp?fileid="+id; xmlHttp.open("GET", url, true);// 異步處理返回 xmlHttp.onreadystatechange = callback; xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); xmlHttp.send() var url = "getNginxStatus"; xmlHttp.open("POST", url, true); xmlHttp.onreadystatechange = getStatusBack; xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); xmlHttp.send(xml);
Java 代碼的http請求:
Http請求類
package wzh.Http;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.Map;public class HttpRequest {/*** 向指定URL發送GET方法的請求* * @param url* 發送請求的URL* @param param* 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。* @return URL 所代表遠程資源的響應結果*/public static String sendGet(String url, String param) {String result = "";BufferedReader in = null;try {String urlNameString = url + "?" + param;URL realUrl = new URL(urlNameString);// 打開和URL之間的連接URLConnection connection = realUrl.openConnection();// 設置通用的請求屬性connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 建立實際的連接 connection.connect();// 獲取所有響應頭字段Map<String, List<String>> map = connection.getHeaderFields();// 遍歷所有的響應頭字段for (String key : map.keySet()) {System.out.println(key + "--->" + map.get(key));}// 定義 BufferedReader輸入流來讀取URL的響應in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("發送GET請求出現異常!" + e);e.printStackTrace();}// 使用finally塊來關閉輸入流finally {try {if (in != null) {in.close();}} catch (Exception e2) {e2.printStackTrace();}}return result;}/*** 向指定 URL 發送POST方法的請求* * @param url* 發送請求的 URL* @param param* 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。* @return 所代表遠程資源的響應結果*/public static String sendPost(String url, String param) {PrintWriter out = null;BufferedReader in = null;String result = "";try {URL realUrl = new URL(url);// 打開和URL之間的連接URLConnection conn = realUrl.openConnection();// 設置通用的請求屬性conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 發送POST請求必須設置如下兩行conn.setDoOutput(true);conn.setDoInput(true);// 獲取URLConnection對象對應的輸出流out = new PrintWriter(conn.getOutputStream());// 發送請求參數out.print(param);// flush輸出流的緩沖out.flush();// 定義BufferedReader輸入流來讀取URL的響應in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("發送 POST 請求出現異常!"+e);e.printStackTrace();}//使用finally塊來關閉輸出流、輸入流finally{try{if(out!=null){out.close();}if(in!=null){in.close();}}catch(IOException ex){ex.printStackTrace();}}return result;} }?調用方法:
public static void main(String[] args) {//發送 GET 請求String s=HttpRequest.sendGet("http://localhost:6144/Home/RequestString", "key=123&v=456");System.out.println(s);//發送 POST 請求String sr=HttpRequest.sendPost("http://localhost:6144/Home/RequestPostString", "key=123&v=456");System.out.println(sr);}
總結
以上是生活随笔為你收集整理的http 请求 与其同步与异步请求的通透讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jdbc Template 介绍和 sp
- 下一篇: NSIS FileOpen打开读写文件操