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标志的任何信息, ...
随机推荐
- poj 3281Dining(网络流 拆点)
题目链接:http://poj.org/problem?id=3281 题目大意:John养了N只奶牛,他为奶牛准备了F个食物和D个饮料,但是每只奶牛只对其中的一些饮料和食物感兴趣,现在请制定一些方案 ...
- 程序员必需知道的Chrome使用技巧(入门篇)
浏览器版本 Chrome Canary 新增一些没有经过Google工程师的测试或使用的浏览器功能版本.Chrome Dev让大多数开发人员主要使用此版本来测试对浏览器的重大版本功能版本.Chrome ...
- MyBatis(8)——联表多对一的处理
xml说明: <!--column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性--> <resultMap id="唯一的标识" ...
- php 填写pdf 表单
最近接到新的任务,要求把pdf的文档,编辑后发邮件 首先pdf表单提交,需要用到这个东西pdftk,GitHub地址:https://github.com/mikehaertl/php-pdftk 首 ...
- 基于XML装配bean的解析-Bean的作用域
一.Bean的种类1.普通bean:<bean id="" class="A"> ,spring直接创建A实例,并返回. 2.FactoryBe ...
- 2019冬季PAT甲级第三题
#define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ]; ]; ]; int main(){ ...
- (原创)SoapUI学习(2)- POST请求
1.新建Project,右键Projects->New REST Project,可以不填直接点击OK,之后通过rename重命名.(如果这里添加URL,则直接达到第三步的图) 2.右键新建的工 ...
- Docker学习笔记(1):CentOS7安装Docker
Docker是一个基于Go语言实现的开源应用容器引擎,通过对应用组件的封装.分发.部署.运行等生命周期的管理,使程序及其运行环境能够做到"一次封装,到处运行". Docker架构 ...
- Centos7编译安装kafka-manager-2.0.0.2
一.kafka-manager简介 项目地址为:https://github.com/yahoo/kafka-manager 为了简化开发者和服务工程师维护Kafka集群的工作,yahoo构建了一个叫 ...
- JS高级---实例对象使用属性和方法层层的搜索 (实例对象-->原型对象-->报错)
实例对象使用属性和方法层层的搜索: 实例对象使用的属性或者方法, 先在实例中查找, 找到了则直接使用: 找不到则, 再去实例对象的__proto__指向的原型对象prototype中找, 找到了则 ...