不知道大家是否想过这样一个问题,比如说我们登陆淘宝之后,点击订单,点击购物车,这些都是自己的信息。通过前面的学习,我们也知道 HTTP 协议是无状态的,我们与淘宝的服务器之间,只是通过一串串字节在交流。我们发送请求,就是发给服务器一串字节流,服务器收到后作出响应,也返回一串字节流。当我们点击「购物车」,点击「订单」他怎么知道是「我」在查看购物车信息,而不是张三在查看购物车呢?
我们想到一种笨拙的解决办法:当我们点击购物车的时候,系统让你登陆账号密码,登陆之后就能正确访问你的信息了。当我们点击其他信息时,比如「订单」,系统也让你输入账号密码,这样订单信息也能正确访问了。这种方法是一种解决办法,但是给用户带来的体验很不好。cookie 就是用来维持登陆状态的东西。
Cookie 是什么
简单来说就是一串字符串数据,用来区分和辨别不同用户。可以理解为「身份证」,通过身份证这一串数据,我们就能知道是谁在访问服务器。当然这一字符串可能还会包含,Cookie 的过期时间,以及一些安全协议等等。
Cookie 如何维持状态当我们第一次登陆一个网站的时候,我们填写好自己的账号密码信息,向服务器发送登陆请求。服务器根据你传过来的账号密码进行判断,倘若账号密码正确,服务器就会返回登陆成功的信息,并且在返回的 response header 中使用 Set-Cookie
参数,设置一段随机字符串 Cookie。
当我们有了 Cookie 之后,我们发出去的所有请求,浏览器都会帮我们把 Cookie 字符串带上,服务器就根据 Cookie 信息来辨别用户,返回正确的用户信息。
使用 Java 代码获取 Cookie 信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class Crawler {
private static final String COOKIE_URL = "http://47.91.156.35:8000/auth/login"; private static final String MESSAGE_URL = "http://47.91.156.35:8000/auth"; private static final CloseableHttpClient httpclient = HttpClients.createDefault();
public static String loginAndGetResponse(String username, String password) throws IOException {
HttpPost httpPost = new HttpPost(COOKIE_URL); httpPost.addHeader("Content-Type", "application/json"); httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36");
Map<String, String> map = new HashMap<>(16); map.put("username", username); map.put("password", password);
HttpEntity entity = new StringEntity(JSON.toJSONString(map)); httpPost.setEntity(entity); CloseableHttpResponse loginResponse = httpclient.execute(httpPost);
String result = getMessageByCookie(loginResponse.getFirstHeader("Set-Cookie").getValue()); loginResponse.close();
return result; }
public static String getMessageByCookie(String cookie) throws IOException { HttpGet httpGet = new HttpGet(MESSAGE_URL); httpGet.addHeader("Cookie", cookie); CloseableHttpResponse response = httpclient.execute(httpGet);
HttpEntity entity1 = response.getEntity(); InputStream is = entity1.getContent(); String html = IOUtils.toString(is, "UTF-8"); EntityUtils.consume(entity1); response.close(); return html; } }
|
使用给定的用户名 username 和密码 password 进行模拟登录,然后获取服务器返回的 Cookie
的值,并把获取到的 Cookie 带到下一次的请求中去访问个人信息。
首先新建一个 HttpPost 对象,添加所需的头部信息。 Content-type
告诉服务器我们要给服务器发送的数据类型。 User-Agent
让我们模拟浏览器的方式去访问,避免被服务器屏蔽请求。
使用 Map 对象将我们得账号密码存储起来,接着使用 JSON 工具转化为字符串,放到请求体中,执行 POST 请求,把返回的头部信息 Set-Cookie
的值拿到。
使用 getMessageByCookie
方法,把获取到的 Cookie 值当做参数传入。方法中发送了一个 HttpGet 请求,把Cookie加到请求头中,发送到服务器,并把返回的 body 数据转化为字符串,返回去。
这样就是一次使用获取 Cookie ,并使用 Cookie 的简单访问。