postman在post数据时出现问题

postman在post数据时出现问题(flask接口):这个端口是在容器里的,我启动docker容器的命令如下:docker run -itd --name cj_seal_ocr_v1.5 -p 0.0.0.0:16666:8888 --gpus all cj-seal:v1

img


这是我给postman的地址 请求方式是post
这是我的接口代码:

@app.route('/compare', methods=['POST', "GET"])
def job():
    fileOne = request.files.get("fileOne")
    fileTwo = request.files.get("fileTwo")
    filename_one = fileOne.filename.lower()
    filename_two = fileTwo.filename.lower()
    if filename_one.split(".")[-1] not in ["pdf", "jpg", "png"] or filename_two.split(".")[-1] not in ["pdf", "jpg",
                                                                                                       "png"]:
        return jsonify({"code": 2998, "message": "请确认上传文件的后缀格式"})
    fileOneFolder = str(uuid.uuid4())
    fileTwoFolder = str(uuid.uuid4())
    try:
        shutil.rmtree(fileOneFolder)
        shutil.rmtree(fileTwoFolder)
    except Exception as e:
        print("删除原始文件夹失败")
    os.makedirs(fileOneFolder)
    os.makedirs(fileTwoFolder)
    fileOne.filename = filename_one
    fileTwo.filename = filename_two
    if filename_one.split(".")[-1] in ["pdf"]:
        pdf_to_image(fileOneFolder, fileOne)
    else:
        fileOne.save(fileOneFolder + "/" + filename_one)
    if filename_two.split(".")[-1] in ["pdf"]:
        pdf_to_image(fileTwoFolder, fileTwo)
    else:
        fileTwo.save(fileTwoFolder + "/" + filename_two)
    one_seals, two_seals = main(fileOneFolder, fileTwoFolder)
    result = get_result(one_seals, two_seals)
    try:
        shutil.rmtree(fileOneFolder)
        shutil.rmtree(fileTwoFolder)
    except Exception as e:
        print("处理完数据,删除文件夹失败")
    return jsonify(result)


if __name__ == '__main__':
    app.run("0.0.0.0", 5000)

报错如下:

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">

    <title>Jupyter Notebook</title>
    <link id="favicon" rel="shortcut icon" type="image/x-icon"
        href="/static/base/images/favicon.ico?v=50afa725b5de8b00030139d09b38620224d4e7dba47c07ef0e86d4643f30c9bfe6bb7e1a4a1c561aa32834480909a4b6fe7cd1e17f7159330b6b5914bf45a880">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link rel="stylesheet"
        href="/static/components/jquery-ui/themes/smoothness/jquery-ui.min.css?v=fb45616eef2c454960f91fcd2a04efeda84cfacccf0c5d741ba2793dc1dbd6d3ab01aaae6485222945774c7d7a9a2e9fb87e0d8ef1ea96893aa6906147a371bb"
        type="text/css" />
    <link rel="stylesheet"
        href="/static/components/jquery-typeahead/dist/jquery.typeahead.min.css?v=5edf53bf6bb9c3b1ddafd8594825a7e2ed621f19423e569c985162742f63911c09eba2c529f8fb47aebf27fafdfe287d563347f58c1126b278189a18871b6a9a"
        type="text/css" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">



    <link rel="stylesheet"
        href="/static/style/style.min.css?v=b092d0a2da5df36f2b073ddb4eafcd6c8094c4fa21b6dcd3f7185ce16c04ad66424083d785b81607a26b4b85b69a560574ada7db75262c886655f99d651c482e"
        type="text/css" />

    <style type="text/css">
        /* disable initial hide */
        div#header,
        div#site {
            display: block;
        }
    </style>

    <link rel="stylesheet" href="/custom/custom.css" type="text/css" />
    <script
        src="/static/components/es6-promise/promise.min.js?v=bea335d74136a63ae1b5130f5ac9a50c6256a5f435e6e09fef599491a84d834a8b0f011ca3eaaca3b4ab6a2da2d3e1191567a2f171e60da1d10e5b9d52f84184"
        type="text/javascript" charset="utf-8"></script>
    <script
        src="/static/components/react/react.production.min.js?v=9a0aaf84a316c8bedd6c2ff7d5b5e0a13f8f84ec02442346cba0b842c6c81a6bf6176e64f3675c2ebf357cb5bb048e0b527bd39377c95681d22468da3d5de735"
        type="text/javascript"></script>
    <script
        src="/static/components/react/react-dom.production.min.js?v=6fc58c1c4736868ff84f57bd8b85f2bdb985993a9392718f3b4af4bfa10fb4efba2b4ddd68644bd2a8daf0619a3844944c9c43f8528364a1aa6fc01ec1b8ae84"
        type="text/javascript"></script>
    <script
        src="/static/components/create-react-class/index.js?v=894ad57246e682b4cfbe7cd5e408dcd6b38d06af4de4f3425991e2676fdc2ef1732cbd19903104198878ae77de12a1996de3e7da3a467fb226bdda8f4618faec"
        type="text/javascript"></script>
    <script
        src="/static/components/requirejs/require.js?v=d37b48bb2137faa0ab98157e240c084dd5b1b5e74911723aa1d1f04c928c2a03dedf922d049e4815f7e5a369faa2e6b6a1000aae958b7953b5cc60411154f593"
        type="text/javascript" charset="utf-8"></script>
    <script>
        require.config({
          
          urlArgs: "v=20230404091240",
          
          baseUrl: '/static/',
          paths: {
            'auth/js/main': 'auth/js/main.min',
            custom : '/custom',
            nbextensions : '/nbextensions',
            kernelspecs : '/kernelspecs',
            underscore : 'components/underscore/underscore-min',
            backbone : 'components/backbone/backbone-min',
            jed: 'components/jed/jed',
            jquery: 'components/jquery/jquery.min',
            json: 'components/requirejs-plugins/src/json',
            text: 'components/requirejs-text/text',
            bootstrap: 'components/bootstrap/dist/js/bootstrap.min',
            bootstraptour: 'components/bootstrap-tour/build/js/bootstrap-tour.min',
            'jquery-ui': 'components/jquery-ui/jquery-ui.min',
            moment: 'components/moment/min/moment-with-locales',
            codemirror: 'components/codemirror',
            termjs: 'components/xterm.js/xterm',
            typeahead: 'components/jquery-typeahead/dist/jquery.typeahead.min',
          },
          map: { // for backward compatibility
              "*": {
                  "jqueryui": "jquery-ui",
              }
          },
          shim: {
            typeahead: {
              deps: ["jquery"],
              exports: "typeahead"
            },
            underscore: {
              exports: '_'
            },
            backbone: {
              deps: ["underscore", "jquery"],
              exports: "Backbone"
            },
            bootstrap: {
              deps: ["jquery"],
              exports: "bootstrap"
            },
            bootstraptour: {
              deps: ["bootstrap"],
              exports: "Tour"
            },
            "jquery-ui": {
              deps: ["jquery"],
              exports: "$"
            }
          },
          waitSeconds: 30,
      });

      require.config({
          map: {
              '*':{
                'contents': 'services/contents',
              }
          }
      });

      // error-catching custom.js shim.
      define("custom", function (require, exports, module) {
          try {
              var custom = require('custom/custom');
              console.debug('loaded custom.js');
              return custom;
          } catch (e) {
              console.error("error loading custom.js", e);
              return {};
          }
      })

    document.nbjs_translations = {"domain": "nbjs", "locale_data": {"nbjs": {"": {"domain": "nbjs"}}}};
    document.documentElement.lang = navigator.language.toLowerCase();
    </script>




</head>

<body class="" dir="ltr">

    <noscript>
        <div id='noscript'>
            Jupyter Notebook 需要 JavaScript。<br>
      请启用它以继续。
  </div>
    </noscript>

    <div id="header" role="navigation" aria-label="Top Menu">
        <div id="header-container" class="container">
            <div id="ipython_notebook" class="nav navbar-brand"><a href="/tree" title='指示板'>
                    <img src='/static/base/images/logo.png?v=a2a176ee3cee251ffddf5fa21fe8e43727a9e5f87a06f9c91ad7b776d9e9d3d5e0159c16cc188a3965e00375fb4bc336c16067c688f5040c0c2d4bfdb852a9e4' alt='Jupyter Notebook'/>
  </a></div>











        </div>
        <div class="header-bar"></div>



    </div>

    <div id="site">


        <div class="error">

            <h1>403 : Forbidden</h1>



            <p>错误:</p>
            <div class="traceback-wrapper">
                <pre class="traceback">&#39;_xsrf&#39; argument missing from POST</pre>
            </div>


        </div>


    </div>







    <script type='text/javascript'>
        require(['jquery'], function($) {
  // scroll long tracebacks to the bottom
  var tb = $(".traceback")[0];
  tb.scrollTop = tb.scrollHeight;
});
    </script>


    <script type='text/javascript'>
        function _remove_token_from_url() {
    if (window.location.search.length <= 1) {
      return;
    }
    var search_parameters = window.location.search.slice(1).split('&');
    for (var i = 0; i < search_parameters.length; i++) {
      if (search_parameters[i].split('=')[0] === 'token') {
        // remote token from search parameters
        search_parameters.splice(i, 1);
        var new_search = '';
        if (search_parameters.length) {
          new_search = '?' + search_parameters.join('&');
        }
        var new_url = window.location.origin + 
                      window.location.pathname + 
                      new_search + 
                      window.location.hash;
        window.history.replaceState({}, "", new_url);
        return;
      }
    }
  }
  _remove_token_from_url();
    </script>
</body>

</html>

我想知道的是 这是我代码本身写的有问题还是我post的方式有问题 然后问题该如何解决

缺少_xsrf参数,这个参数应该是csrf验证用的

img

配置下Jupyter NotebookApp.disable_check_xsrfBool这个为true(默认false)关闭csrf验证。


NotebookApp.disable_check_xsrfBool
Default: False

Disable cross-site-request-forgery protection

Jupyter notebook 4.3.1 introduces protection from cross-site request forgeries, requiring API requests to either:

originate from pages served by this server (validated with XSRF cookie and token), or

authenticate with a token

Some anonymous compute resources still desire the ability to run code, completely without authentication. These services can disable all authentication and security checks, with the full knowledge of what that implies.

或者在jupyter中运行代码测试什么的

403 : Forbidden 接口有权限问题

获取PostMan Post请求参数失败

可以借鉴下
https://blog.csdn.net/m0_48740201/article/details/127329531

引用new bing部分回答作答:
根据您的描述,似乎您无法使用 Postman 将数据发送到 Flask 应用程序。您提供的 Flask 代码本身没有任何问题,因此这可能是与 Postman 的设置有关。

请确保在 Postman 中使用正确的端口号和 URL。从您的代码中,我们可以看出您的 Flask 应用程序在端口号 5000 上运行。但是,在您的 Docker 命令中,您将容器的端口号映射到 16666。因此,正确的 URL 是 http://localhost:16666/compare
而不是
http://localhost:5000/compare

另外,请确保在 Postman 中正确设置请求头和请求体。在 Flask 应用程序中,您正在接收包含名为 fileOne 和 fileTwo 的文件的 POST 请求。因此,在 Postman 中,您应该选择 form-data 选项,并在 key 中分别为 fileOne 和 fileTwo 添加文件,而不是在 raw 标签中添加 JSON 数据。

引用chatGPT作答,根据您提供的信息,我注意到您在Docker容器中运行Flask应用程序,并在端口16666上公开了Flask应用程序。在Postman中,您使用http://localhost:16666/compare%E4%BD%9C%E4%B8%BAAPI%E7%AB%AF%E7%82%B9%E7%9A%84URL%EF%BC%8C%E5%B9%B6%E5%B0%86%E5%85%B6%E4%BD%9C%E4%B8%BAPOST%E8%AF%B7%E6%B1%82%E8%BF%9B%E8%A1%8C%E8%AE%BF%E9%97%AE%E3%80%82%E7%84%B6%E8%80%8C%EF%BC%8C%E6%82%A8%E4%BC%BC%E4%B9%8E%E9%81%87%E5%88%B0%E4%BA%86%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98%E3%80%82

根据您的错误,您的应用程序似乎正在运行Jupyter Notebook,而不是Flask应用程序。请确保您正确运行了Flask应用程序,并且正在使用正确的URL。如果您已经这样做了,请检查您的代码以确保它正在正确处理来自Postman的请求。

此外,我还建议您检查Docker容器是否正确运行。您可以使用docker ps命令来列出所有正在运行的容器,并查看是否有一个正在运行您的Flask容器。

状态吗 403 表示接口被禁用 说明你参数少了 接口是对的 那应该就是csrf

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
根据报错信息,可以看到错误原因是缺少 _xsrf 参数。这是因为 Flask 默认开启了 CSRF 保护机制,需要在 POST 请求时带上 _xsrf 参数。可以在 HTML 表单中加入一个隐藏域来自动生成这个参数,或者手动在 POST 请求中添加 _xsrf 参数。

尝试修改 POST 请求,在请求的 headers 中加入 _xsrf 参数,在 Flask 后端中同时处理该参数,代码如下:

POST 请求:

在 POST 请求中,设置 headers 中添加 _xsrf 参数,例如:

import requests

url = "http://<host>:<port>/compare"已黑化的小白 files = {'fileOne': open('fileOne.pdf', 'rb'), 'fileTwo': open('fileTwo.pdf', 'rb')}
xsrf = 'xxxxxxxxxxxxxxxxxxxx'
headers = {'_xsrf': xsrf}
response = requests.post(url, headers=headers, files=files)
print(response.text)

在请求 headers 中添加了 _xsrf 参数,其值为一个随机字符串。

Flask 后端:

在 Flask 后端,需要获取 _xsrf 参数的值。可以采用 Flask-WTF 等插件来自动生成 _xsrf 字段,也可以手动获取。手动获取 _xsrf 参数的代码如下:

from flask import Flask, request
import os
import uuid
import shutil
from flask import jsonify

app = Flask(__name__)

@app.route('/compare', methods=['POST', 'GET'])
def compare():
    xsrf = request.headers.get('_xsrf')
    # 在这里处理 POST 请求提交的文件
    return jsonify({})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=16666)

这段代码通过 request.headers.get('_xsrf') 获取了 _xsrf 参数的值。
如果我的回答解决了您的问题,请采纳!