java 連接遠程服務器 URLconnection

網絡中的URL(Uniform Resource Locator)是統一資源定位符的簡稱。它表示Internet上某一資源的地址。通過URL我們可以訪問Internet上的各種網絡資源,比如最常見的WWW,FTP站點。 URL可以被認爲是指向互聯網資源的“指針”,通過URL可以獲得互聯網資源相關信息,包括獲得URL的InputStream對象獲取資源的信息,以及一個到URL所引用遠程對象的連接URLConnection。 URLConnection對象可以向所代表的URL發送請求和讀取URL的資源。通常,創建一個和URL的連接,需要如下幾個步驟:

  1. 創建URL對象,並通過調用openConnection方法獲得URLConnection對象;

  2. 設置URLConnection參數和普通請求屬性;

  3. 向遠程資源發送請求;

  4. 遠程資源變爲可用,程序可以訪問遠程資源的頭字段和通過輸入流來讀取遠程資源返回的信息。

這裏需要重點討論一下第三步:如果只是發送GET方式請求,使用connect方法建立和遠程資源的連接即可;如果是需要發送POST方式的請求,則需要獲取URLConnection對象所對應的輸出流來發送請求。這裏需要注意的是,由於GET方法的參數傳遞方式是將參數顯式追加在地址後面,那麼在構造URL對象時的參數就應當是包含了參數的完整URL地址,而在獲得了URLConnection對象之後,就直接調用connect方法即可發送請求。而POST方法傳遞參數時僅僅需要頁面URL,而參數通過需要通過輸出流來傳遞。

package com.wa.axis2.test;


import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import org.junit.Test;

public class Upload {
    @Test
	public void upload(){
		try {
			URL url=new URL("http://localhost:8090/audit/UploadFileHttpServlet?name=hello");
			HttpURLConnection urlConnection=(HttpURLConnection) url.openConnection();
			
			urlConnection.setDoInput(true);
			urlConnection.setDoOutput(true);
			urlConnection.setUseCaches(false);
			urlConnection.setRequestProperty("Content-Type", "application/octet-stream");
			urlConnection.setRequestProperty("ReturnFileUploadPath", "D://test//a.txt");
			
			File file=new File("E:\\aa.txt");
			int len=0;
			byte[] by=new byte[1024*1024];
			BufferedInputStream bi=new BufferedInputStream(new FileInputStream(file));
			while((len=bi.read(by))!=-1){
				urlConnection.getOutputStream().write(by, 0, len);
			}
			
			/**
			*推送json格式的數據
			 JSONObject obj = new JSONObject();
		            obj.put("Title", "測試標題3");
		            obj.put("ContentText", "內容不可控制");
		            obj.put("NoticeType", "jsgc");
		            obj.put("NoticePubType", "zbgs");
		            obj.put("DisplayStartTime", "2015-09-28");
		            obj.put("DisplayEndTime", "2015-09-28");
		            OutputStreamWriter out= new OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8");
		            out.write(obj.toString());
		            out.flush();
		           */ 
			
			// 獲得響應狀態
			int responseCode = urlConnection.getResponseCode();
			if (HttpURLConnection.HTTP_OK == responseCode) {
				// 當正確響應時處理數據
				System.out.println("");
				System.out.println("Http Response OK...");
				// 處理響應流,必須與服務器響應流輸出的編碼一致
				StringBuffer responseBuffer = new StringBuffer();
				String readLine;

				BufferedReader responseReader = new BufferedReader(new InputStreamReader(
						urlConnection.getInputStream(),
						"utf-8"));
				while ((readLine = responseReader.readLine()) != null) {
					responseBuffer.append(readLine).append("n");
				}

				System.out.println("Http Response:" + responseBuffer);
				responseReader.close();
			}
			bi.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}


服務器servlet代碼如下:

protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		    String name = request.getParameter("name");
	        String path=request.getHeader("ReturnFileUploadPath");
	        System.out.println(path);
	        File file=new File(path);
	        if(!file.exists()){
	        	file.getParentFile().mkdirs();
	        }
	        //讀取發送來的文件並且保存到本地
	        BufferedOutputStream bo=new BufferedOutputStream(new FileOutputStream(file));
	        int len=0;
	        byte[] by=new byte[1024*1024];
	        while((len=request.getInputStream().read(by))!=-1){
	        	bo.write(by, 0, len);
	        }
	        
	        /*
	        *解析json數據
	        *StringBuffer sf=new StringBuffer();
		String readline="";
		BufferedReader bf=new BufferedReader(new InputStreamReader(request.getInputStream()));
		while((readline=bf.readLine())!=null){
			sf.append(readline);
		}
       System.out.println(sf.toString());
       
       JSONArray jsonArray=JSONArray.fromObject(new String[]{sf.toString()});
	  //解析json數據
	   for(Object o:jsonArray){
		 JSONObject jsonObject=JSONObject.fromObject(o);
	 	 System.out.println(jsonObject.get("Title")+"\t\t"+jsonObject.get("ContentText"));
	  }
	  //解析json數據轉化爲對象
	  
	   for(Object obj:jsonArray){
    	   Student st=(Student) json2Bean(((JSONObject) obj).toString(), Student.class);
    	   System.out.println(st.getUsername()+":"+st.getDesc());
       }
	  
	  */
	  
	  /*
	  *  /******************* 最新的解析方法
	  * 使用的是 org.json.JSONArray 和JSONObject 類上面使用的是json_lib_2.4_jdk15.jar
	   ***********************/
         JSONArray jsonArray = null;
         // 初始化list數組對象
         ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
         jsonArray = new JSONArray(jsonStr);
         for (int i = 0; i < jsonArray.length(); i++) {
             JSONObject jsonObject = jsonArray.getJSONObject(i);
             // 初始化map數組對象
             HashMap<String, Object> map = new HashMap<String, Object>();
             map.put("logo", jsonObject.getString("logo"));
             map.put("logoLunbo", jsonObject.getString("logoLunbo"));
             map.put("biaoTi", jsonObject.getString("biaoTi"));
             map.put("yuanJia", jsonObject.getString("yuanJia"));
             map.put("xianJia", jsonObject.getString("xianJia"));
             map.put("id", jsonObject.getInt("id"));
             list.add(map);
         }
         return list;*/
	        
	        bo.flush();
	        bo.close();
	        response.setContentType("text/plain; charset=UTF-8");
	        response.setCharacterEncoding("UTF-8");
	        response.getWriter().write("It is ok!");
	}
	
	
	public static Object json2Bean(String json,Class cla){
		JSONObject jsonObject=JSONObject.fromObject(json);
		return JSONObject.toBean(jsonObject, cla);
	}
//get方式發送請求
    public static void main(String[] args) {
		String httpUrl = "http://apis.baidu.com/apistore/weatherservice/cityinfo";
		String httpArg = "cityname=%E5%8C%97%E4%BA%AC";
		String jsonResult = request(httpUrl, httpArg);
		System.out.println(jsonResult);

	}
   
	/**GET
	 * @param urlAll
	 *            :請求接口
	 * @param httpArg
	 *            :參數
	 * @return 返回結果
	 */
	public static String request(String httpUrl, String httpArg) {
	    BufferedReader reader = null;
	    String result = "";
	    StringBuffer sbf = new StringBuffer();
	    httpUrl = httpUrl + "?" + httpArg;

	    try {
	        URL url = new URL(httpUrl);
	        HttpURLConnection connection = (HttpURLConnection) url
	                .openConnection();
	        connection.setRequestMethod("GET");
	        // 填入apikey到HTTP header
	        connection.setRequestProperty("apikey",  "123456");
	        connection.connect();
	        InputStream is = connection.getInputStream();
	        reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
	        String strRead = null;
	        while ((strRead = reader.readLine()) != null) {
	            sbf.append(strRead);
	            sbf.append("\r\n");
	        }
	        reader.close();
	        result = sbf.toString();
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	    return result;
	}
	
	
	/**POST
	 * @param urlAll
	 *            :請求接口
	 * @param httpArg
	 *            :參數
	 * @return 返回結果
	 */
	public static String request2(String httpUrl, String httpArg) {
	    BufferedReader reader = null;
	    String result = null;
	    StringBuffer sbf = new StringBuffer();

	    try {
	        URL url = new URL(httpUrl);
	        HttpURLConnection connection = (HttpURLConnection) url
	                .openConnection();
	        connection.setRequestMethod("POST");
	        connection.setRequestProperty("Content-Type",
	                        "application/x-www-form-urlencoded");
	        // 填入apikey到HTTP header
	        connection.setRequestProperty("apikey",  "0258a35a375578ca6898f4cd5c497616");
	        connection.setDoOutput(true);
	        connection.getOutputStream().write(httpArg.getBytes("UTF-8"));//獲取輸出流,寫入參數
	        connection.connect();
	        InputStream is = connection.getInputStream();
	        reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
	        String strRead = null;
	        while ((strRead = reader.readLine()) != null) {
	            sbf.append(strRead);
	            sbf.append("\r\n");
	        }
	        reader.close();
	        result = sbf.toString();
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	    return result;
	}
	
	/**
	 * Apache HttpClient模塊 利用HttpPost來發送post請求
	 * @param uriAPI
	 * @param params
	 * @return
	 *
	 * @version:v1.0
	 * @author:liuwei
	 * @date:2015-9-15 下午5:05:17
	 */
	public String doPost(String uriAPI,Map<String ,String> params )
    {
    	String result = "";
    	HttpPost httpRequst = new HttpPost(uriAPI);//創建HttpPost對象
    	
    	List <NameValuePair> nvps  = new ArrayList<NameValuePair>();

        Set<String> keySet = params.keySet();
        for(String key : keySet) {
        	nvps.add(new BasicNameValuePair(key, params.get(key)));
        }
    	
    	try {
    		//使用HttpPost類的setEntity方法設置請求參數。參數則必須用NameValuePair[]數組存儲
			httpRequst.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8));
			//使用DefaultHttpClient類的execute方法發送HTTP GET或HTTP POST請求,並返回HttpResponse對象
			HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequst);
		    //if(httpResponse.getStatusLine().getStatusCode() == 200)
		    //{
		    	//通過HttpResponse接口的getEntity方法返回響應信息
		    	HttpEntity httpEntity = httpResponse.getEntity();
		    	result = EntityUtils.toString(httpEntity);//取出應答字符串
		   // }
		} 
		catch (Exception e) {
			e.printStackTrace();
			result = e.getMessage().toString();
		}
    	return result;
    }


注意事項;

總結:a:) HttpURLConnection的connect()函數,實際上只是建立了一個與服務器的tcp連接,並沒有實際發送http請求。

    無論是post還是get,http請求實際上直到HttpURLConnection的getInputStream()這個函數裏面才正式發送出去。

       b:) 在用POST方式發送URL請求時,URL請求參數的設定順序是重中之重, 對connection對象的一切配置(那一堆set函數) 都必須要在connect()函數執行之前完成。而對outputStream的寫操作,又必須要在inputStream的讀操作之前。 這些順序實際上是由http請求的格式決定的。

    如果inputStream讀操作在outputStream的寫操作之前,會拋出例外:

    java.net.ProtocolException: Cannot write output after reading input.......

      

       c:) http請求實際上由兩部分組成,

    一個是http頭,所有關於此次http請求的配置都在http頭裏面定義,所以在服務端需要使用getHeader來獲取參數,request.getHeader("ReturnFileUploadPath");

     一個是正文content。

    connect()函數會根據HttpURLConnection對象的配置值生成http頭部信息,因此在調用connect函數之前, 就必須把所有的配置準備好。

       d:) 在http頭後面緊跟着的是http請求的正文,正文的內容是通過outputStream流寫入的,

    實際上outputStream不是一個網絡流,充其量是個字符串流,往裏面寫入的東西不會立即發送到網絡,

    而是存在於內存緩衝區中,待outputStream流關閉時,根據輸入的內容生成http正文。


    至此,http請求的東西已經全部準備就緒。在getInputStream()函數調用的時候,就會把準備好的http請求 正式發送到服務器了,然後返回一個輸入流,用於讀取服務器對於此次http請求的返回信息。由於http 請求在getInputStream的時候已經發送出去了(包括http頭和正文),因此在getInputStream()函數  之後對connection對象進行設置(對http頭的信息進行修改)或者寫入outputStream(對正文進行修改) 都是沒有意義的了,執行這些操作會導致異常的發生。



http協議補充:

HTTP由兩部分組成:請求和響應。當你在Web瀏覽器中輸入一個URL時,瀏覽器將根據你的要求創建併發送請求,該請求包含所輸入的URL以及一些與瀏覽器本身相關的信息。當服務器收到這個請求時將返回一個響應,該響應包括與該請求相關的信息以及位於指定URL(如果有的話)的數據。直到瀏覽器解析該響應並顯示出網頁(或其他資源)爲止。

HTTP請求

HTTP請求的格式如下所示:

<request-line>
<headers>
<blank line>
[<request-body>]

在HTTP請求中,第一行必須是一個請求行(request line),用來說明請求類型、要訪問的資源以及使用的HTTP版本。緊接着是一個首部(header)小節,用來說明服務器要使用的附加信息。在首部之後是一個空行,再此之後可以添加任意的其他數據[稱之爲主體(body)]。

在HTTP中,定義了多種請求類型,通常我們關心的只有GET請求和POST請求。只要在Web瀏覽器上輸入一個URL,瀏覽器就將基於該URL向服務器發送一個GET請求,以告訴服務器獲取並返回什麼資源。對於www.baidu.com的GET請求如下所示:

GET / HTTP/1.1
Host: 
www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive

請求行的第一部分說明了該請求是GET請求。該行的第二部分是一個斜槓(/),用來說明請求的是該域名的根目錄。該行的最後一部分說明使用的是HTTP 1.1版本(另一個可選項是1.0)。那麼請求發到哪裏去呢?這就是第二行的內容。

第2行是請求的第一個首部,HOST。首部HOST將指出請求的目的地。結合HOST和上一行中的斜槓(/),可以通知服務器請求的是www.baidu.com/(HTTP 1.1才需要使用首部HOST,而原來的1.0版本則不需要使用)。第三行中包含的是首部User-Agent,服務器端和客戶端腳本都能夠訪問它,它是瀏覽器類型檢測邏輯的重要基礎。該信息由你使用的瀏覽器來定義(在本例中是Firefox 1.0.1),並且在每個請求中將自動發送。最後一行是首部Connection,通常將瀏覽器操作設置爲Keep-Alive(當然也可以設置爲其他值)。注意,在最後一個首部之後有一個空行。即使不存在請求主體,這個空行也是必需的。

要發送GET請求的參數,則必須將這些額外的信息附在URL本身的後面。其格式類似於:

URL ? name1=value1&name2=value2&..&nameN=valueN

該信息稱之爲查詢字符串(query string),它將會複製在HTTP請求的請求行中,如下所示:

GET /books/?name=Professional%20Ajax HTTP/1.1
Host: 
www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive

注意,爲了將文本“Professional Ajax”作爲URL的參數,需要編碼處理其內容,將空格替換成%20,這稱爲URL編碼(URL encoding),常用於HTTP的許多地方(JavaScript提供了內建的函數來處理URL編碼和解碼)。“名稱—值”(name—value)對用 & 隔開。絕大部分的服務器端技術能夠自動對請求主體進行解碼,併爲這些值的訪問提供一些邏輯方式。當然,如何使用這些數據還是由服務器決定的。

另一方面,POST請求在請求主體中爲服務器提供了一些附加的信息。通常,當填寫一個在線表單並提交它時,這些填入的數據將以POST請求的方式發送給服務器。

以下就是一個典型的POST請求:

POST / HTTP/1.1
Host: 
www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive

name=Professional%20Ajax&publisher=Wiley

從上面可以發現, POST請求和GET請求之間有一些區別。首先,請求行開始處的GET改爲了POST,以表示不同的請求類型。你會發現首部Host和User-Agent仍然存在,在後面有兩個新行。其中首部Content-Type說明了請求主體的內容是如何編碼的。瀏覽器始終以application/ x-www-form- urlencoded的格式編碼來傳送數據,這是針對簡單URL編碼的MIME類型。首部Content-Length說明了請求主體的字節數。在首部Connection後是一個空行,再後面就是請求主體。與大多數瀏覽器的POST請求一樣,這是以簡單的“名稱—值”對的形式給出的,其中name是Professional Ajax,publisher是Wiley。你可以以同樣的格式來組織URL的查詢字符串參數。

下面是一些最常見的請求頭:

    Accept:瀏覽器可接受的MIME類型。
    Accept - Charset:瀏覽器可接受的字符集。
    Accept - Encoding:瀏覽器能夠進行解碼的數據編碼方式,比如gzip。Servlet能夠向支持gzip的瀏覽器返回經gzip編碼的HTML頁面。許多情形下這可以減少5到10倍的下載時間。
    Accept - Language:瀏覽器所希望的語言種類,當服務器能夠提供一種以上的語言版本時要用到。
    Authorization:授權信息,通常出現在對服務器發送的WWW - Authenticate頭的應答中。
    Connection:表示是否需要持久連接。如果Servlet看到這裏的值爲“Keep - Alive”,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久連接),它就可以利用持久連接的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點,Servlet需要在應答中發送一個Content - Length頭,最簡單的實現方法是:先把內容寫入ByteArrayOutputStream,然後在正式寫出內容之前計算它的大小。
    Content - Length:表示請求消息正文的長度。
    Cookie:這是最重要的請求頭信息之一,參見後面《Cookie處理》一章中的討論。
    From:請求發送者的email地址,由一些特殊的Web客戶程序使用,瀏覽器不會用到它。
    Host:初始URL中的主機和端口。
    If - Modified - Since:只有當所請求的內容在指定的日期之後又經過修改才返回它,否則返回304“Not Modified”應答。
    Pragma:指定“no - cache”值表示服務器必須返回一個刷新後的文檔,即使它是代理服務器而且已經有了頁面的本地拷貝。
    Referer:包含一個URL,用戶從該URL代表的頁面出發訪問當前請求的頁面。
    User - Agent:瀏覽器類型,如果Servlet返回的內容與瀏覽器類型有關則該值非常有用。
    UA - Pixels,UA - Color,UA - OS,UA - CPU:由某些版本的IE瀏覽器所發送的非標準的請求頭,表示屏幕大小、顏色深度、操作系統和CPU類型。


HTTP響應

如下所示,HTTP響應的格式與請求的格式十分類似:
<status-line>
<headers>
<blank line>
[<response-body>]

正如你所見,在響應中唯一真正的區別在於第一行中用狀態信息代替了請求信息。狀態行(status line)通過提供一個狀態碼來說明所請求的資源情況。以下就是一個HTTP響應的例子:

HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122

<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>

在本例中,狀態行給出的HTTP狀態代碼是200,以及消息OK。狀態行始終包含的是狀態碼和相應的簡短消息,以避免混亂。最常用的狀態碼有:
◆200 (OK): 找到了該資源,並且一切正常。
◆304 (NOT MODIFIED): 該資源在上次請求之後沒有任何修改。這通常用於瀏覽器的緩存機制。
◆401 (UNAUTHORIZED): 客戶端無權訪問該資源。這通常會使得瀏覽器要求用戶輸入用戶名和密碼,以登錄到服務器。
◆403 (FORBIDDEN): 客戶端未能獲得授權。這通常是在401之後輸入了不正確的用戶名或密碼。
◆404 (NOT FOUND): 在指定的位置不存在所申請的資源。

在狀態行之後是一些首部。通常,服務器會返回一個名爲Data的首部,用來說明響應生成的日期和時間(服務器通常還會返回一些關於其自身的信息,儘管並非是必需的)。接下來的兩個首部大家應該熟悉,就是與POST請求中一樣的Content-Type和Content-Length。在本例中,首部Content-Type指定了MIME類型HTML(text/html),其編碼類型是ISO-8859-1(這是針對美國英語資源的編碼標準)。響應主體所包含的就是所請求資源的HTML源文件(儘管還可能包含純文本或其他資源類型的二進制數據)。瀏覽器將把這些數據顯示給用戶。

注意,這裏並沒有指明針對該響應的請求類型,不過這對於服務器並不重要。客戶端知道每種類型的請求將返回什麼類型的數據,並決定如何使用這些數據。


網站日誌中,我們經常會看到很多返回的http代碼,如201、304、404、500等等。可是這些具體的返回的HTTP代碼究竟什麼含義呢,在此做一下知識普及吧,記不住不要緊,到時候看看就行了,但最主要的幾個還要要清楚的。

 一些常見的狀態碼爲:

  200 - 服務器成功返回網頁

  404 - 請求的網頁不存在

  503 - 服務器超時

  下面提供 HTTP 狀態碼的完整列表。點擊鏈接可瞭解詳情。您也可以訪問 HTTP 狀態碼上的 W3C 頁獲取更多信息。

  1xx(臨時響應)

  表示臨時響應並需要請求者繼續執行操作的狀態碼。

  100(繼續)請求者應當繼續提出請求。服務器返回此代碼表示已收到請求的第一部分,正在等待其餘部分。

  101(切換協議)請求者已要求服務器切換協議,服務器已確認並準備切換。

  2xx (成功)

  表示成功處理了請求的狀態碼。

  200(成功)服務器已成功處理了請求。通常,這表示服務器提供了請求的網頁。如果是對您的 robots.txt 文件顯示此狀態碼,則表示 Googlebot 已成功檢索到該文件。

  201(已創建)請求成功並且服務器創建了新的資源。

  202(已接受)服務器已接受請求,但尚未處理。

  203(非授權信息)服務器已成功處理了請求,但返回的信息可能來自另一來源。

  204(無內容)服務器成功處理了請求,但沒有返回任何內容。

  205(重置內容)服務器成功處理了請求,但沒有返回任何內容。與 204 響應不同,此響應要求請求者重置文檔視圖(例如,清除表單內容以輸入新內容)。

  206(部分內容)服務器成功處理了部分 GET 請求。

  3xx (重定向)

  要完成請求,需要進一步操作。通常,這些狀態碼用來重定向。Google 建議您在每次請求中使用重定向不要超過 5 次。您可以使用網站管理員工具查看一下 Googlebot 在抓取重定向網頁時是否遇到問題。診斷下的網絡抓取頁列出了由於重定向錯誤導致 Googlebot 無法抓取的網址。

  300(多種選擇)針對請求,服務器可執行多種操作。服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。

  301(永久移動)請求的網頁已永久移動到新位置。服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。您應使用此代碼告訴 Googlebot 某個網頁或網站已永久移動到新位置。

  302(臨時移動)服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來響應以後的請求。此代碼與響應 GET 和 HEAD 請求的 301 代碼類似,會自動將請求者轉到不同的位置,但您不應使用此代碼來告訴 Googlebot 某個網頁或網站已經移動,因爲 Googlebot 會繼續抓取原有位置並編制索引。

  303(查看其他位置)請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。對於除 HEAD 之外的所有請求,服務器會自動轉到其他位置。

  304(未修改)自從上次請求後,請求的網頁未修改過。服務器返回此響應時,不會返回網頁內容。

  如果網頁自請求者上次請求後再也沒有更改過,您應將服務器配置爲返回此響應(稱爲 If-Modified-Since HTTP 標頭)。服務器可以告訴搜索引擎的蜘蛛/機器人 自從上次抓取後網頁沒有變更,進而節省帶寬和開銷。

  .

  305(使用代理)請求者只能使用代理訪問請求的網頁。如果服務器返回此響應,還表示請求者應使用代理。

  307(臨時重定向)服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來響應以後的請求。此代碼與響應 GET 和 HEAD 請求的 301 代碼類似,會自動將請求者轉到不同的位置,但您不應使用此代碼來告訴 Googlebot 某個頁面或網站已經移動,因爲 Googlebot 會繼續抓取原有位置並編制索引。

  4xx(請求錯誤)

  這些狀態碼錶示請求可能出錯,妨礙了服務器的處理。

  400(錯誤請求)服務器不理解請求的語法。

  401(未授權)請求要求身份驗證。對於登錄後請求的網頁,服務器可能返回此響應。

  403(禁止)服務器拒絕請求。如果您在 Googlebot 嘗試抓取您網站上的有效網頁時看到此狀態碼(您可以在 Google 網站管理員工具診斷下的網絡抓取頁面上看到此信息),可能是您的服務器或主機拒絕了 Googlebot 訪問。

  404(未找到)服務器找不到請求的網頁。例如,對於服務器上不存在的網頁經常會返回此代碼。

  如果您的網站上沒有 robots.txt 文件,而您在 Google 網站管理員工具"診斷"標籤的 robots.txt 頁上看到此狀態碼,則這是正確的狀態碼。但是,如果您有 robots.txt 文件而又看到此狀態碼,則說明您的 robots.txt 文件可能命名錯誤或位於錯誤的位置(該文件應當位於頂級域,名爲 robots.txt)。

  如果對於 Googlebot 抓取的網址看到此狀態碼(在"診斷"標籤的 HTTP 錯誤頁面上),則表示 Googlebot 跟隨的可能是另一個頁面的無效鏈接(是舊鏈接或輸入有誤的鏈接)。

  405(方法禁用)禁用請求中指定的方法。

  406(不接受)無法使用請求的內容特性響應請求的網頁。

  407(需要代理授權)此狀態碼與 401(未授權)類似,但指定請求者應當授權使用代理。如果服務器返回此響應,還表示請求者應當使用代理。

  408(請求超時)服務器等候請求時發生超時。

  409(衝突)服務器在完成請求時發生衝突。服務器必須在響應中包含有關衝突的信息。服務器在響應與前一個請求相沖突的 PUT 請求時可能會返回此代碼,以及兩個請求的差異列表。

  410(已刪除)如果請求的資源已永久刪除,服務器就會返回此響應。該代碼與 404(未找到)代碼類似,但在資源以前存在而現在不存在的情況下,有時會用來替代 404 代碼。如果資源已永久移動,您應使用 301 指定資源的新位置。

  411(需要有效長度)服務器不接受不含有效內容長度標頭字段的請求。

  412(未滿足前提條件)服務器未滿足請求者在請求中設置的其中一個前提條件。

  413(請求實體過大)服務器無法處理請求,因爲請求實體過大,超出服務器的處理能力。

  414(請求的 URI 過長)請求的 URI(通常爲網址)過長,服務器無法處理。

  415(不支持的媒體類型)請求的格式不受請求頁面的支持。

  416(請求範圍不符合要求)如果頁面無法提供請求的範圍,則服務器會返回此狀態碼。

  417(未滿足期望值)服務器未滿足"期望"請求標頭字段的要求。

  5xx(服務器錯誤)

  這些狀態碼錶示服務器在處理請求時發生內部錯誤。這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

  500(服務器內部錯誤)服務器遇到錯誤,無法完成請求。

  501(尚未實施)服務器不具備完成請求的功能。例如,服務器無法識別請求方法時可能會返回此代碼。

  502(錯誤網關)服務器作爲網關或代理,從上游服務器收到無效響應。

  503(服務不可用)服務器目前無法使用(由於超載或停機維護)。通常,這只是暫時狀態。

  504(網關超時)服務器作爲網關或代理,但是沒有及時從上游服務器收到請求。

  505(HTTP 版本不受支持)服務器不支持請求中所用的 HTTP 協議版本。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章