常见HTTP请求方式

目录

概括

1. OPTIONS

2. GET

3. HEAD

4. POST

4.1 form表单

5. PUT

6. PATCH

7. DELETE

8.TRACE

9. CONNECT


概括

在http/1.1协议中,定义了8种访问指定资源的方法,他们分别为

OPTIONS
GET
HEAD
POST
PUT
PATCH
DELETE
TRACE
CONNECT
为了更好的讲解和演示这9种http请求的方法,我用flask写了一个简单的服务程序
 

import json
from flask import Flask, request, make_response, jsonify


app = Flask(__name__)


@app.route("/book", methods=['HEAD', 'GET', 'POST', 'PUT', 'DELETE', 'TRACE'])
def book():
    method = request.method
    if method == 'HEAD':
        return book_head()
    elif method == 'GET':
        return book_get()
    elif method == 'POST':
        #return book_post_form()
        return book_post_json()
    elif method == 'PUT':
        return book_put()
    elif method == 'DELETE':
        return book_delete()

def book_head():
    return jsonify({'name': 'python进阶教程', 'price': 35.5})


def book_get():
    return jsonify({'name': 'python进阶教程', 'price': 35.5})


def book_post_form():
    name = request.form['name']
    price = float(request.form['price'])
    print(name, price)

    return jsonify({'status': 1, 'msg': '新增成功'})


def book_post_json():
    data = json.loads(request.get_data())
    print(data)
    return jsonify({'status': 1, 'msg': '新增成功'})


def book_put():
    data = json.loads(request.get_data())
    print(data)
    return jsonify({'status': 1, 'msg': '修改成功'})


def book_delete():
    data = json.loads(request.get_data())
    print(data)
    return jsonify({'status': 1, 'msg': '删除成功'})



if __name__ == '__main__':
    app.run(debug=True)

这个服务只提供了一个URI资源,下面逐个介绍这8种请求资源的方法

1. OPTIONS


向服务器发送options方法,可以测试服务器功能是否正常,服务器会返回这个资源所支持的HTTP请求方法,在javascript中,使用XMLHttpRequest对象进行CORS跨域资源共享时,会先使用options方法进行嗅探,以此判断对指定资源是否具有访问权限。

flask框架会自动处理OPTIONS和HEAD请求,我在指定'/book'所支持的methods中并没有写OPTIONS,但使用requests发送OPTIONS请求,可以得到正常响应
 

mport requests

url = 'http://127.0.0.1:5000/book'


def test_options():
    res = requests.options(url)
    print(res.headers)

test_options()

esponse 的headers里,会返回Allow 首部,其内容为"TRACE, GET, HEAD, PATCH, POST, DELETE, OPTIONS, PUT",这表示,请求'/book'时,服务器支持这么多的请求方法。

2. GET


GET方法用于显示的请求指定资源,通常,GET方法只用于读取数据,这在restful接口中尤为严格,GET方法绝不应该应用于会产生副作用的非幂等操作中。

所谓幂等,是一个数学与计算机概念,在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。

本示例中,服务端收到GET请求后,返回一段json数据,发送请求的客户端程序如下
 

import requests

url = 'http://127.0.0.1:5000/book'


def test_get():
    params = {'name': 'python'}
    res = requests.get(url, params=params)
    print(res.text)

test_get()

你应该已经注意到,发送get请求也是可以携带参数的,而不只是post可以.

不同之处在于,post请求的参数放在dody体中,而get请求的参数放在url中,服务端收到的请求的完整url是

http://127.0.0.1:5000/book?name=python
GET请求的URL在浏览器里是极容易暴露的,因此用户的敏感信息不可以明文传输。
 

3. HEAD


HEAD方法在各个方面均与GET方法相同,唯一不同之处在于,服务器收到HEAD请求,不会将body里的内容返回给客户端,在本实例中,虽然响应HEAD请求时,明确的使用return语句返回了数据

return jsonify({'name': 'python进阶教程', 'price': 35.5})


但客户端不会收到这些数据,既然收不到数据,HEAD方法还有什么用处呢?

HEAD方法通常用来获取资源的信息,这些信息都蕴藏在响应头信息中,比如Content-Length, 客户端只是想知道自己将要请求的资源有多大,而并不是真的想要获取这份资源,那么就可以使用HEAD方法进行查看,虽然返回的response里没有body数据,但header里的部首和使用GET请求时返回的完全一样。

一个比较实用的场景如下,有一个很大的文件需要下载,单线程下载会很慢,那么就可以考虑使用多线程,每个线程只下载资源的一段,这个利用Range部首很容易就做到,那么整件时间最关键的就是获得资源的大小,你可以使用GET请求,但更便捷的方法是用HEAD请求,毕竟GET请求会返回整个文件。

4. POST


post用于向指定资源提交数据,在restful风格的接口里,post用于新增数据。

post请求提交的数据放在请求的body体中,post提交的数据一般有两种格式,一种是form表单,一种是json数据

4.1 form表单


我们在登录某个网站的后台时,在网页上填写用户名和密码,点击回车后的提交过程就是post请求,请求的Content-Type值为 application/x-www-form-urlencoded 下面是模拟客户端提交form表单的一段代码
 

import requests

url = 'http://127.0.0.1:5000/book'


def test_form_post():
    data = {'name': 'python', 'price': 45.6}
    res = requests.post(url, data=data)
    print(res.text)

test_form_post()

服务端处理这种post请求要使用book_post_form函数,收到的请求body体中,数据为

name=python&price=45.6

lask框架会帮助我们解析这里的内容,我们通过request.form对象即可获得name和price

上面的代码是通过requests库直接提交,如果是通过网页上的form表单进行提交,则form表单应该是如下形式
 

<form action="/book" method="POST">
      <p>name: <input type="text" name="name" /></p >
      <p>price: <input type="text" name="price" /></p >
      <input type="submit" value="提交" />
    </form>

application/x-www-form-urlencoded 是表单默认的提交方式,你也可以通过enctype 来指定提交方式

<form action="/book" method="POST" enctype='application/x-www-form-urlencoded'>

如果你的表单还要上传文件,那么enctype则要设置成multipart/form-data

提交json数据
另一种较为常用的post数据格式是json,下面是一个具体示例
 

import requests

url = 'http://127.0.0.1:5000/book'


def test_json_post():
    data = {'name': 'python', 'price': 45.6}
    res = requests.post(url, json=data)
    print(res.text)

test_json_post()

服务端收到的请求的Content-Type 为application/json,body体中的数据为
 

{"name": "python", "price": 45.6}

不同于form表单数据,json数据需要我们自己写代码从body中取出并loads成字典来使用,具体方法参见flask 服务端程序里的book_post_json函数

5. PUT


put请求方法用于向指定资源上传最新数据,用于更新操作,该方法是幂等操作。同post一样,提交数据时,可以使用form表单或者json格式数据,下面是具体示例
 

import requests

url = 'http://127.0.0.1:5000/book'


def test_put():
    data = {'name': 'python', 'price': 55.6}
    res = requests.put(url, json=data)
    print(res.text)

test_put()

6. PATCH


PATCH方法是HTTP/1.1标准制定之后扩展的方法,和PUT一样,也用于资源的更新,不同之处有两点

PATCH用于资源的部分更新,PUT多用于资源的整体更新
如果资源不存在,使用PATCH时应创建一个新的资源,而PUT则不要求创建新资源
下面是使用patch请求的示例代码
 

import requests

url = 'http://127.0.0.1:5000/book'


def test_patch():
    data = {'name': 'python'}
    res = requests.request('trace', url, json=data)
    print(res.text)

test_patch()

7. DELETE


delete方法用于删除URI所标识的资源,同样是幂等操作
 

import requests

url = 'http://127.0.0.1:5000/book'


def test_delete():
    data = {'name': 'python', 'price': 55.6}
    res = requests.delete(url, json=data)
    print(res.text)


test_delete()

8.TRACE

trace请求方法用于http请求的测试和诊断,根据协议,服务器在收到trace请求后,应回显所收到的数据,即服务器返回自己所收到的数据。

下面是客户端发送trace请求的一个例子

import requests

url = 'http://127.0.0.1:5000/book'


def test_trace():
    data = {'name': 'python'}
    res = requests.request('trace', url, json=data)
    print(res.text)


test_trace()

9. CONNECT


connect请求方法在我们日常的开发工作中是不会遇到的,因为它的作用是让服务器作为代理,让服务器代替用户访问其他网页,其实就是代理服务器。

鉴于connect在日常工作中很难有所应用,因此该请求不提供参考示例,感兴趣的同学可以阅读以下几篇博文

https://www.jianshu.com/p/54357cdd4736
https://blog.csdn.net/aotony_1988/article/details/42005835
https://www.joji.me/zh-cn/blog/the-http-connect-tunnel/
10. 最后啰嗦几句
虽然http协议提供了这么多种方法,但使用的最为频繁的却只有get和post的,甚至是滥用。

restful风格的接口提倡使用http方法来标识区分一个请求操作意图,比如获取数据用get,新增用post,修改用put,删除用delete。

然而在实际工作中,我看到的最多的代码都没有遵守这些规则,而是大量的使用post请求,区分请求意图的方法是使用不同的uri,比如获取数据用get_xx,新增数据用add_xx, 修改数据用modify_xx,删除数据用del_xx, 一个post请求,实现了对同一个资源的四种操作,个人很不喜欢这种风格的接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值