2020-03-23 13:48:52 更新:

  最近看到部分文章阅读量竟然变高了,有点惶恐,希望自己不会误人子弟。这篇文章是非常浅显的 http 协议的一小部分,如果要全面了解 http / 1.1 协议,请移步:RFC 7231

  它是http 1.1 标准规范档案,里面讲述十分详细。(我记得火狐开发者社区也有)

  比如 http1.1 Accept-Encoding 字段中描述了如何压缩 body 进行传输,这点很重要,我最初自己写http客户端的时候还不知道,于是从服务器获得的 html 内容都是乱码,其实这是因为服务端将 body 部分使用 br 、gzip、deflate 等方法进行了编码。并且对其压缩算法也有较详细的描述,简单来说都是基于哈夫曼树的改进和优化(详见 RFC 1951 DEFLATERFC 1951 GZIP

  对各种响应状态码的解释、缓存控制、Session等。

  最后,大家有没有真正的意识到一点呢,其实计算机越学越发现,基本上就是在学习前人与计算机定下的规则呀~,无论哪一个方面(硬件、语言、算法、软件、图片等),然后终将有一天,我们也开始制定一些规则,让别人参与进来。所以对各种协议、文档存储格式等有一定深入了解是非常重要的一件事。

以下为原文:

  先推荐一篇很不错的文章:https://imququ.com/post/four-ways-to-post-data-in-http.html

  说一下,如果是自己编写底层,那么要注意了,不能只有提交数据的类型,还必须要有数据内容的长度,大体这样写即可:

method << "POST / HTTP1/1\r\n";
headers << "Content-Length: 32\r\n";
headers << "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
...
body << "test=1&type=json&time=1513242234";

  请求头部分结束的后面就是请求主体(body),发送的body内容是key-value对应的url source,如果带有中文或其他非英文语种,类似这样:

type=1&message=%E5%8A%A9%E6%89%8B&plat=1&jsonp=jsonp

  需按url编码格式编码。注意不用在字符串尾部加"\r\n"。

  实际上这种类型的提交参数实现了通过接口对服务器后台的数据库进行CRUD操作。

  我之前仅仅只是会用python的requests库,没怎么了解底层,现在自己用C++写爬虫才知道,人家已经帮我们做好了这些事,十分便利,同时也看到了她的强大之处。

  下面用C++测试B站的add接口(发表评论)为例:

#include <iostream>
#include <sstream>
#include "libhttp.hpp" using http::Request;
using std::string;
using std::stringstream; int main()
{
Request r; string url = "https://api.bilibili.com/x/v2/reply/add"; stringstream headers; headers << "Contention: keep-alive\r\n";
headers << "Content-Length: 102\r\n";
headers << "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
headers << "Cookie: xxx\r\n";
headers << "Host: api.bilibili.com\r\n";
headers << "Referer: https://www.bilibili.com/bangumi/play/ep85276\r\n";
headers << "User-agent: xxx\r\n"; string data = "oid=4492528&type=1&message=%E5%8A%A9%E6%89%8B&plat=1&jsonp=jsonp&csrf=14211ebe19f7a1500e3a4d910c9d4b44";
// decode: "oid=4492528&type=1&message=助手&plat=1&jsonp=jsonp&csrf=14211ebe19f7a1500e3a4d910c9d4b44"; r.post(url, "", headers.str(), data, ""); return 0;
}

  

  运行结果:

  到B站上看看:

  测试成功,这里测试环境是Linux CentOS7。

  如果使用python requests模块,可以简单这样写:

# coding=utf8
from requests import request data = {
'oid': '4492528',
'type': '1',
'message': '正片被tx抢走了',
'plat': '1',
'jsonp': 'jsonp',
'csrf': '141500e3a4d910c9d4b44'
} headers = {
'Cookie': 'xxx'
} r = request('post', 'https://api.bilibili.com/x/v2/reply/add', data=data, headers=headers, timeout=1) print r.status_code
print r.text

  她的底层会根据你自定义的headers以及data进行解析,然后补充上一些缺少的重要key-value。

  顺便提下之前在该篇中提到的csrf

  1.旧csrf + 旧cookie:

  2.新csrf + 旧cookie:

  3.旧csrf + 新cookie:


  # 2018-12-15 12:02:22 咳咳,今天回头看了一下这篇文章。。。はつかし。。。emmm,发现自己真是个文盲。。。基本上各大网站的csrf和cookie都是有生命周期的。。。一些网站做得更严谨,可能关闭掉网页就死了,但一般都是通过session来持续一段生命周期,并且csrf是一种名为Cross-site request forgery(跨站请求伪造)的技术,嘛,做过网站应该就明白了。所以,我重新登录,之前的csrf以及cookie当然会失效。。。


  ...然后B站的csrf怎么获得呢?不可能每次都发表评论 + F12看吧,这也太事后诸葛亮了,所以找找还有没有其他方法,当然我也是无意间找到一个办法,当视频播放时,有个接口会每隔几秒钟发送一次请求,其中也带有该视频下通用的csrf,这个接口名为:heartbeat,如图:

  点一下她,在Headers中From Data就可以看见了。

  ps:今天才知道如何查看网站的robots.txt,在浏览器地址栏中输入是格式:http://网站主页/robots.txt,比如B站的:https://www.bilibili.com/robots.txt,上面写清楚了网站中哪些是不允许爬取的。

  参考:

    1.https://www.zhihu.com/question/34980963

    2.http://www.robotstxt.org/robotstxt.html

http协议学习 —— post请求方法提交application/x-www-form-urlencoded类型的数据格式的更多相关文章

  1. 标准Http协议的六种请求方法详解

    标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD 6.Options 但其实我们大部分情况下只用到了GET和POST.如果想设计一个符合RE ...

  2. python学习 —— post请求方法的应用

    声明:本篇仅基于兴趣以及技术研究而对B站曾经发生过的抢楼事件背后相关技术原理进行研究而写.请不要将其作为私利而对B站以及B站用户体验造成影响!谢谢合作!若本文对B站及其用户带来困扰,请联系本人删除本文 ...

  3. HTTP协议的六种请求方法

    抛砖引玉,聊下概念性的东西先: HTTP协议 (Hyper Text Transfer Protocol) HTTP是一个基于TCP/IP通信协议来传递数据,包括html文件.图像.结果等,即是一个客 ...

  4. HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端

    协议简介 协议,自然语言里面就是契约,也是双方或者多方经过协商达成的一致意见; 契约也即类似于合同,自然有甲方123...,乙方123...,哪些能做,哪些不能做; 通信协议,也即是双方通过网络通信必 ...

  5. http学习--常用请求方法和响应状态码

    常用的http请求方法: GET方法:请求服务器资源,并返回 POST方法:向指定资源提交数据进行处理请求(比如说表单,上传文件等).数据被包含在请求体中.POST请求可能会导致新的资源建立或已有资源 ...

  6. HTTP协议、HTTP请求方法、常见状态码、HTTP消息

    HTTP协议 客户端请求,服务端响应.浏览器与服务器不建立持久连接,响应后连接失效. HTTP请求方法 一.GET GET方法用于获取请求页面的指定信息. 二.HEAD 除了服务器不能在响应里返回消息 ...

  7. SpringMVC 学习笔记(请求方法的返回值和参数)

    在用注解对配置 处理器时,一般是一个方法处理一个请求,不同方法的返回类型有着不同的意义. 返回值为 ModelAndView 类型 ModelAndView 是Model 和 View 的一个集合类型 ...

  8. php模拟HTTP协议发送post请求方法

    今天用到php模拟http发送post请求记录 代码如下: <?php $url = 'xxxx.com'; $data = 'a=one&b=two'; $data = urlenco ...

  9. HTTP协议中POST、GET、HEAD、PUT等请求方法以及一些常见错误

    (来源:http://www.tuicool.com/articles/Ermmmyn) HTTP请求方法: 常用方法: Get\Post\Head (1)Get方法. 取回请求URL标志的任何信息, ...

随机推荐

  1. Jquery判断单个checkbox 是否被选中

    jquery判断checked的三种方法: .attr("checked") .prop("checked") .is(":checked" ...

  2. (BFS)1097: Yuchang and Zixiang ‘s maze

    1097: Yuchang and Zixiang ‘s maze Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 863 Solved: 149   De ...

  3. 当map的key为对象时,js无法解析key的属性值

    重写对象的toString方法,按照json数据的规则 然后前台string转json 控制台打印 这个方法不需要引入其他包 如果map的key属性过多,或者key是集合,可以在后台先转json,然后 ...

  4. 计算几何-点与多边形的位置判断-zoj1081Points Within

    This article is made by Jason-Cow.Welcome to reprint.But please post the writer's address. http://ww ...

  5. 1.什么是Mybatis?

    在学习之前我们要回顾以下知识 JDBC Mysql java基础 Maven Junit 什么是 MyBatis? MyBatis 是一款优秀的持久层框架MyBatis 避免了几乎所有的 JDBC 代 ...

  6. 设备驱动基础学习--misc device简单实现

    在Linux驱动中把无法归类的五花八门的设备定义为混杂设备(用miscdevice结构体表述).miscdevice共享一个主设备号MISC_MAJOR(即10),但次设备号不同. 所有的miscde ...

  7. Java 链接mongodb 执行集合查询

    public static String mongodbConnection(String phone){ String sendCode = null; //创建mongodb链接地址 MongoC ...

  8. eclipse的版本代号

    mars为4.5版本号 代号 代号名 发布日期Eclipse 3.1 IO 木卫一,伊奥 2005Eclipse 3.2 Callisto 木卫四,卡里斯托 2006Eclipse 3.3 Europ ...

  9. C++:打开一个文件夹下一系列的文件

    可以用MFC的CFileFind类: FILE *pFile=NULL; CFileFind cff; CString fstr="C:\\page\\*.*"//所以用文件和文件 ...

  10. (原创)Windows下编译的Shell脚本不能再Linux中运行的解决办法

    一.原理 Windows编译的文件和Linux编译的文件格式不太一样,导致在Linux运行Shell脚本的时候会提示:/bin/bash^M: bad interpreter: 没有那个文件或目录. ...