1. 程式人生 > >關於禁用Cookie的問題以及解決辦法

關於禁用Cookie的問題以及解決辦法

Cookie與 Session,一般認為是兩個獨立的東西,Session採用的是在伺服器端保持狀態的方案,而Cookie採用的是在客戶端保持狀態的方案。但為什麼禁用Cookie就不能得到Session呢?因為Session是用Session ID來確定當前對話所對應的伺服器Session,而Session ID是通過Cookie來傳遞的,禁用Cookie相當於失去了Session ID,也就得不到Session了。

如何禁用cookie?

  1、啟動IE;
  2、在“工具”選單上,單擊“Internet選項”,開啟“Internet選項”對話方塊;
  3、單擊“隱私”選項卡,將滑塊上移到更高的隱私級別。如果移動到最頂端則是選擇“阻止所有的Cookie”,此時系統將阻止所有網站的Cookie,而且網站不能讀取計算機上已有的Cookie;
  4、單擊“確定”按鈕。

sessionid是儲存在cookie中的,解決方案如下:
Session URL重寫,保證在客戶端禁用或不支援COOKIE時,仍然可以使用Session

session機制。session機制是一種伺服器端的機制,伺服器使用一種類似於散列表的結構(也可能就是使用散列表)來儲存資訊。

當程式需要為某個客戶端的請求建立一個session時,伺服器首先檢查這個客戶端的請求裡是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端建立過session,伺服器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端建立一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個session id將被在本次響應中返回給客戶端儲存。 儲存這個session id的方式可以採用cookie,這樣在互動過程中瀏覽器可以自動的按照規則把這個標識發揮給伺服器。一般這個cookie的名字都是類似於 SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞迴伺服器。 經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面。還有一種技術叫做表單隱藏欄位。就是伺服器會自動修改表單,新增一個隱藏欄位,以便在表單提交時能夠把session id傳遞迴伺服器。

【URL重寫的示例】

package session;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WelcomeServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); request.getSession(); String url1 = response.encodeURL("/Session/servlet/SessionDemo1");//禁用cookie才重寫,注意禁用cookie後,訪問要用127.0.0.1,不能用localhost String url2 = response.encodeURL("/Session/servlet/SessionDemo2"); //禁用cookie之後無法解決關閉瀏覽器能重新訪問的問題。 out.println("<a href='"+url1+"'>購買 </a>"); out.println("<a href='"+url2+"'>結賬</a>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//購買 index.jsp index.html
//session基於cookie
public class SessionDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession(); //Session建立
        //request.getSession(false);    //不建立session,只獲取session  例如:顯示購物車

        //解決瀏覽器關閉後cookie銷燬的問題:
        String sessionid = session.getId();
        Cookie cookie = new Cookie("JSESSIONID",sessionid);
        cookie.setPath("/Session");
        cookie.setMaxAge(30*60);
        response.addCookie(cookie);

        session.setAttribute("name", "洗衣機");
        //30分鐘沒使用之後(不管有無關閉瀏覽器),Session才銷燬(預設,可控制時間)
        //配置方法:在web.xml檔案中配置<session-config>裡面配置一個<session-timeout>並且設定時間值
        //程式碼摧毀方法:session.invalidate();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}


----------


//解決瀏覽器關閉後session銷燬的問題:
String sessionid = session.getId();
Cookie cookie = new Cookie("JSESSIONID",sessionid);
cookie.setPath("/Session");
cookie.setMaxAge(30*60);
response.addCookie(cookie);

【解決瀏覽器關閉後session銷燬的原因】:
sessionId是一個cookie,max-age預設為-1,即關閉瀏覽器後sessionId就會清空 
sessionId(cookie)清空後,自然就無法找到對應的session,所以session就失效了

【解決方法】:
設定上述程式碼,新增cookie的失效時間,
        30分鐘沒使用之後(不管有無關閉瀏覽器),Session才銷燬(預設,可控制時間)
        其他session失效時間配置方法:在web.xml檔案中配置<session-config>裡面配置一個<session-timeout>並且設定時間值
        程式碼摧毀方法:session.invalidate();



----------


package session;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//結賬
public class SessionDemo2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        HttpSession session = request.getSession();
        String product = (String)session.getAttribute("name");
        out.write("你購買的商品是:"+product);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

  URL地址重寫是對客戶端不支援Cookie的解決方案。URL地址重寫的原理是將該使用者Session的id資訊重寫到URL地址中。伺服器能夠解析重寫後的URL獲取Session的id。這樣即使客戶端不支援Cookie,也可以使用Session來記錄使用者狀態。HttpServletResponse類提供了encodeURL(String url)實現URL地址重寫,該方法會自動判斷客戶端是否支援Cookie。如果客戶端支援Cookie,會將URL原封不動地輸出來。如果客戶端不支援Cookie,則會將使用者Session的id重寫到URL中。

  注意:TOMCAT判斷客戶端瀏覽器是否支援Cookie的依據是請求中是否含有Cookie。儘管客戶端可能會支援Cookie,但是由於第一次請求時不會攜帶任何Cookie(因為並無任何Cookie可以攜帶),URL地址重寫後的地址中仍然會帶有jsessionid。當第二次訪問時伺服器已經在瀏覽器中寫入Cookie了,因此URL地址重寫後的地址中就不會帶有jsessionid了。