http协议学习 —— post请求方法提交application/x-www-form-urlencoded类型的数据格式
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 DEFLATE、RFC 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类型的数据格式的更多相关文章
- 标准Http协议的六种请求方法详解
标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD 6.Options 但其实我们大部分情况下只用到了GET和POST.如果想设计一个符合RE ...
- python学习 —— post请求方法的应用
声明:本篇仅基于兴趣以及技术研究而对B站曾经发生过的抢楼事件背后相关技术原理进行研究而写.请不要将其作为私利而对B站以及B站用户体验造成影响!谢谢合作!若本文对B站及其用户带来困扰,请联系本人删除本文 ...
- HTTP协议的六种请求方法
抛砖引玉,聊下概念性的东西先: HTTP协议 (Hyper Text Transfer Protocol) HTTP是一个基于TCP/IP通信协议来传递数据,包括html文件.图像.结果等,即是一个客 ...
- HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端
协议简介 协议,自然语言里面就是契约,也是双方或者多方经过协商达成的一致意见; 契约也即类似于合同,自然有甲方123...,乙方123...,哪些能做,哪些不能做; 通信协议,也即是双方通过网络通信必 ...
- http学习--常用请求方法和响应状态码
常用的http请求方法: GET方法:请求服务器资源,并返回 POST方法:向指定资源提交数据进行处理请求(比如说表单,上传文件等).数据被包含在请求体中.POST请求可能会导致新的资源建立或已有资源 ...
- HTTP协议、HTTP请求方法、常见状态码、HTTP消息
HTTP协议 客户端请求,服务端响应.浏览器与服务器不建立持久连接,响应后连接失效. HTTP请求方法 一.GET GET方法用于获取请求页面的指定信息. 二.HEAD 除了服务器不能在响应里返回消息 ...
- SpringMVC 学习笔记(请求方法的返回值和参数)
在用注解对配置 处理器时,一般是一个方法处理一个请求,不同方法的返回类型有着不同的意义. 返回值为 ModelAndView 类型 ModelAndView 是Model 和 View 的一个集合类型 ...
- php模拟HTTP协议发送post请求方法
今天用到php模拟http发送post请求记录 代码如下: <?php $url = 'xxxx.com'; $data = 'a=one&b=two'; $data = urlenco ...
- HTTP协议中POST、GET、HEAD、PUT等请求方法以及一些常见错误
(来源:http://www.tuicool.com/articles/Ermmmyn) HTTP请求方法: 常用方法: Get\Post\Head (1)Get方法. 取回请求URL标志的任何信息, ...
随机推荐
- MyBatis知识点整理
1.MyBatis一般使用步骤 1.1获取Configuration实例或编写配置文件 //获取Configuration实例的样例 TransactionFactory transactionFac ...
- 【做题笔记】P1042 乒乓球
坑 #1:输入有若干行,但处理的时候要看成一个整体的信息.比如说第一行最后一局比分是 2:1 ,这时不算比完,这个比分要继承到第二行的信息中继续处理. 坑 #2:一局结束,当且仅当其中一方比分大于等于 ...
- ubuntu 下的ftp详细配置
FTP(文件传输协议)是一个较老且最常用的标准网络协议,用于在两台计算机之间通过网络上传/下载文件.然而, FTP 最初的时候并不安全,因为它仅通过用户凭证(用户名和密码)传输数据,没有进行加密. 警 ...
- 线性筛-三合一,强大O(n)
校内CJOJ2395by Jesse Liu 筛法三合一 Euler.Möbius.Prime函数 基于数论的积性函数 gcd(a,b)=1 则 ƒ(ab)=ƒ(a)ƒ(b) #include & ...
- AcWing 861. 二分图的最大匹配 匈牙利算法
#include <cstring> #include <iostream> #include <algorithm> using namespace std; , ...
- Go递归函数
package main import "fmt" func main() { /* 递归函数(recursion):一个函数自己调用自己,就叫做递归函数. 递归函数要有一个出口, ...
- 【C语言】写一个函数,并调用该函数求两个整数的最大公约数和最小公倍数
程序分析: 在数学中,两个数的最小公倍数=两个数的乘积/两数的最大公约数. 求两个数的最大公约数,运用辗转相除法:已知两个整数M和N,假定M>N,则求M%N. 如果余数为0,则N即为所求:如果余 ...
- 【Vue路由系统详述】
目录 路由命名 路由参数 路由参数的实现原理 子路由 子路由之append 动态绑定属性 子路由之append升级版 子路由之非append 路由重定向 手动路由 路由钩子 在路径中去掉"# ...
- sublime-text3 安装 emmet 插件
下载sublime,http://www.sublimetext.com/ 安装package control :https://packagecontrol.io/ins... 这个地址需要翻墙,访 ...
- matplotlib动态图subplots()和subplot()不同及参数
一.fig,ax = subplots(nrows,ncols,sharex,sharey,squeeze,subplot_kw,gridspec_kw,**fig_kw) 创建画布和子图 nrow ...