Python urllib.request.Request发送GET请求、POST请求(带Headers)

问题描述

访问一个接口,需要跳转到另一个接口。

请求方式有GET和POST,且需要带上Headers。




效果

Python urllib.request.Request发送GET请求、POST请求(带Headers)_第1张图片
参数正确传回




解决方案

urllib.request.urlopen()可以传数据但无法直接传Headers,因此需要结合urllib.request.Request()

get请求的转发比较麻烦,需要拼接url,并且使用urllib.parse.quote()对中文做特殊处理。

post请求直接转发即可。




代码

index.html
get和post请求传相同的参数,且带中文


<head>
    <title>Python带Headers转发GET、POST请求title>
    <meta charset="utf-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">script>
head>

<body>
<button id="get" type="button">GET请求button>
<br><br>
<button id="post" type="button">POST请求button>
body>
<script>
    $("#get").click(function () {
        //get请求
        console.log("get请求");
        var data = {
            "name": "XerCis",
            "subject": "语文",
            "grade": 80
        };
        var headers = {
            'Ts': new Date().getTime()
        };
        $.ajax({
            type: "GET",
            url: "/test",
            data: data,
            headers: headers,
            dataType: "json",
            contentType: "application/json",
            success: function (response) {
                console.log(response)
            }
        });
    });

    $("#post").click(function () {
        //post请求
        console.log("post请求");
        var data = {
            "name": "XerCis",
            "subject": "语文",
            "grade": 80
        };
        var headers = {
            'Ts': new Date().getTime()
        };
        $.ajax({
            type: "POST",
            url: "/test",
            data: JSON.stringify(data),
            headers: headers,
            dataType: "json",
            contentType: "application/json",
            success: function (response) {
                console.log(response)
            }
        });
    });
script>
html>

app1.py
用于转发请求

# -*- coding: utf-8 -*-
# @Author  : XerCis
# @Function: 请求转发,相当于中转
import string
from urllib.parse import quote, urljoin
from urllib.request import Request, urlopen
import tornado.web
import tornado.ioloop
from tornado.options import define, options

define("port", default=1111, help="运行端口", type=int)


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")


class TestHandler(tornado.web.RequestHandler):
    def get(self):
        '''转发get请求需拼接url'''
        data = self.request.arguments
        get_params = None  # 手动拼接url
        for key in data.keys():
            if not get_params:
                get_params = '?' + key + '=' + data[key][0].decode()
            else:
                get_params += '&' + key + '=' + data[key][0].decode()
        url = "http://localhost:2222/test"
        url = urljoin(url, get_params)
        url = quote(url, safe=string.printable)  # 不加这句参数传中文会出错
        headers = self.request.headers
        request = Request(url, headers=headers)  # 不带data时默认method为GET
        response = urlopen(request)
        response = response.read()
        self.write(response)

    def post(self):
        url = "http://localhost:2222/test"
        data = self.request.body
        headers = self.request.headers
        request = Request(url, data, headers)  # 带data时默认method为POST
        response = urlopen(request)
        response = response.read()
        self.write(response)


if __name__ == "__main__":
    app = tornado.web.Application(
        [
            (r"/", MainHandler),
            (r"/test", TestHandler),
        ],
    )
    app.listen(options.port)
    print("http://localhost:{}/".format(options.port))
    tornado.ioloop.IOLoop.current().start()

app2.py
真正处理请求的接口

# -*- coding: utf-8 -*-
# @Author  : XerCis
# @Function: 处理请求
import tornado.web
import tornado.ioloop
from tornado.options import define, options

define("port", default=2222, help="运行端口", type=int)


class TestHandler(tornado.web.RequestHandler):
    def get(self):
        name = self.get_argument('name')
        subject = self.get_argument('subject')
        grade = self.get_argument('grade')
        ts = self.request.headers['Ts']
        response = {
            'name': name,
            'subject': subject,
            'grade': grade,
            'ts': ts
        }
        self.write(response)

    def post(self):
        self.write(self.request.body)


if __name__ == "__main__":
    app = tornado.web.Application(
        [
            (r"/test", TestHandler),
        ],
    )
    app.listen(options.port)
    print("【已启动】http://localhost:{}/".format(options.port))
    tornado.ioloop.IOLoop.current().start()




参考文献

  1. python 字典字符串转字典——urllib.request.Request发送get,post请求
  2. python3 urlopen打开包含中文的url
  3. urllib.request — Extensible library for opening URLs

你可能感兴趣的:(Python)