HTTP协议中的“报头”(header)和 “正文“ (body)详解_crazy_xieyi的博客-CSDN博客_http头和body
Fiddler抓包:下载、安装及使用_crazy_xieyi的博客-CSDN博客
文章目录
Cookie是属于报头(header)里面的,详情请参考博客:HTTP协议中的“报头”(header)和 “正文“ (body)详解_crazy_xieyi的博客-CSDN博客_http头和body请求“报头”(header)、请求 “正文“ (body)以及响应 “报头“ (header)、响应 “正文“ (body)详解https://blog.csdn.net/crazy_xieyi/article/details/126745105
Cookie是HTTP协议中的一个字段,同时也是浏览器在客户端这边保存数据的一种比较古老的方式。Cookie是由服务器产生的,通过HTTP响应的Set-Cookie字段来进行设置,并返回给浏览器。Cookie是在浏览器这边进行储存的,浏览器会根据域名/地址来分别储存Cookie。在浏览器的下次请求中Cookie会被自动添加到请求中,发送给服务器。其中Cookie是以键值对结构的字符串来进行储存的,这里的键值对都是程序员自定义的。
Session叫做“会话”。因为HTTP协议本身是无状态的,如果对服务器进行两次请求,对于服务器来说是感知不到这两次请求的关联关系的。在实际开发中,要求服务器是需要有状态的,比如:当用户完成登陆之后,后续再访问这个网站的时候,服务器就能知道这个用户的身份信息了(前提是浏览器没有清除缓存)。Session是在服务器端进行储存的,Session类似一个hash表,key就是sessionId。value就是程序员自定义的数据(用户的身份信息.......)。
Cookie与Session之间是需要相互配合的。相互配合流程如下:

在这个场景中,服务器返回的set-cookie里面不一定要放sessionId,其实也可以直接把用户信息序列化通过Set-Cookie返回给浏览器。只是Session是一种常见的做法,这样的做法的好处就是方便实现“注销操作”,在服务器这边直接就把session中对应的键值对删了就行。同时,通过session返回也是可以保护用户的隐私的。
| 方法 | 描述 |
|
|
|
|
|
|
| 方法 | 描述 |
|
|
|
| 方法 | 描述 |
|
|
|
|
|
|
|
|
|
| 方法 | 描述 |
|
|
|
|
|
|
|
|
|
<body>
<form action="login" method="post">
用户名:<input type="text" name="username">
<br>
密码:<input type="password" name="password">
<br>
<input type="submit" value="登录">
</form>
</body>
服务器代码-IndexServlet
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//根据当前用户请求中的sesionId,获取到用户信息,并显示到页面上
resp.setContentType("text/html;charset=utf-8");
//1.判断当前用户是否已经登录(请求中有没有sessionId,以及sessionId是否合法)
//如果会话不存在,此处在这里就不能创建了,只能查询,不是登录
HttpSession httpSession = req.getSession(false);
if (httpSession == null){
//没有会话,说明当前用户没有登录,就重定向到登录页面
resp.sendRedirect("login.html");
return;
}
//2.如果用户已经登录,就可以从HttpSession中拿到用户信息了
String username = (String)httpSession.getAttribute("username");
Integer loginCount = (Integer) httpSession.getAttribute("loginCount");
loginCount = loginCount + 1;
httpSession.setAttribute("loginCount",loginCount);
//3.返回一个html页面
StringBuilder html = new StringBuilder();
html.append("<div>用户:" + username + "</div>");
html.append("<div>访问次数:" + loginCount + "</div>");
resp.getWriter().write(html.toString());
}
}
服务器代码-LoginServlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//1.先从请求的body中读取用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
//2.判定用户名和密码是否正确(这里测试就直接使用固定用户名和密码了
if (!"zhangsan".equals(username) || !"1234".equals(password)){
resp.getWriter().write("用户名或密码不正确!");
return;
}
System.out.println("登录成功!");
//3.登录成功就创建会话(不存在会话就会创建
//会话是根据请求中的sessionId来查的,sessionId在Cookie中
//但是此时是首次登录,此时请求中是没有Cookie的,因为Cookie是服务器返回的
//此时就会触发“找不到就创建”这样的流程
//同时这里进行的操作是:先创建出一个HttpSession对象(作为value),然后会自动生成一个
//随机的字符串,作为sessionId(作为Key),然后自动把key和value插入到hash表中
//同时把这个生成的sessionId 通过 Set-Cookie 字段返回
HttpSession httpSession = req.getSession(true);
//此时可以存入自定义的信息(比如用户身份信息......
httpSession.setAttribute("username","zhangsan");
httpSession.setAttribute("loginCount",0); //记录访问次数
//4.让页面跳转到主页,使用重定向即可
resp.sendRedirect("index");
}
}
其中交互过程如下:(以下会用到Fiddler进行抓包分析Fiddler抓包:下载、安装及使用_crazy_xieyi的博客-CSDN博客我们在学习HTTP协议的时候就可以利用Fiddler这个抓包工具。因为HTTP是一个文本格式的协议,我们可以通过Fiddler抓包, 来分析HTTP请求/响应的细节。https://blog.csdn.net/crazy_xieyi/article/details/126709702)
客户端给服务器的第一次交互,是一个登录请求。
请求:

这里登录成功后,就创建了一个session 对象,同时生成了一个sessionId。

响应:

响应里面就可以看到Set-Cookie这个字段,JSESSIONID=E682780C1B1D7FA633FB998DE0E0E038就是Servlet生成的sessionId,key就是JSESSIONID,value就是后面一串十六进制的数字。
然后正是因为这个Location: index,因为这个重定向,就触发了浏览器与服务器的第二次交互。
第二次交互,是一个访问主页的请求。
请求:

这里我们可以看到,在第二次的请求中就自动带了Cookie,而且你会发现此时第二次的请求与第一次的响应中的Cookie值是一样的,然后服务器就会根据Cookie里面的sessionId去查找匹配,然后返回对应的页面给浏览器。
响应:

我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解