代码之家  ›  专栏  ›  技术社区  ›  Denny Weinberg

Angular6 HttpClient POST和flask-HttpClient和curl请求之间的后端内容差异

  •  0
  • Denny Weinberg  · 技术社区  · 6 年前

    我在用HttpClient做一个帖子:

    return this.http.post(`reporting/report/generate/${code}`, {'mimetype': mimetype, 'input': value}, {responseType: mimetype});
    

    使用以下mimetype针对我的API服务器: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

    在服务器端(通过nginx和uwsgi),我正在运行flask,代码如下(裁剪后):

        outputStream = io.BytesIO()
    
        workbook = xlsxwriter.Workbook(outputStream)
        worksheet = workbook.add_worksheet(Report.name())
    
        [...]
    
        worksheet.write(0, 0, 'YY', 'XX')
    
        workbook.close()
    
        output = outputStream.getvalue()
        outputStream.close()
    
        return Response(output, mimetype=mimetype)
    

    回到angular,我使用blobURL等来下载我的文件,但这并不重要。 问题是,当我从angular发出Http请求时,我的Excel文件被破坏,当我使用curl执行完全相同的请求(从Chrome网络选项卡复制)时,它是正常的。

    但是:我在服务器端写了一个temp xlsx文件,两个文件都可以。

    output 我发现有些字节是不同的:

    b'PK\x03\x04\x14\x00\x00\x00\x08\x00\x13}\x15M\xf5\x8e\x0eH\xb9\x01\x00\x00I\x04\x00\x00\x18\...docProps/app.xmlPK\x01\x02\x14\x03\x14\x00\x00\x00\x08\x00\x13}\x15M\x9c\xed\xd2_%\x01\x00\x00P\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00
    

    与。

    b'PK\x03\x04\x14\x00\x00\x00\x08\x003}\x15M\xf5\x8e\x0eH\xb9\x01\x00\x00I\x04\x00\x00\...docProps/app.xmlPK\x01\x02\x14\x03\x14\x00\x00\x00\x08\x003}\x15M\xa5\xc4\xa4$%\x01\x00\x00P\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x81E\x06\x00\x00docProps/core.xmlPK\x01\x02\x14\x03\
    

    diff

    我找了好几个小时都没找到问题。 奇怪的是,临时文件在这两种情况下都是可以的,但是表示方式显示出一点不同。

    我还分析了这些要求,发现有一点不同:

    <Request 'http://lsdev01/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1' [POST]>
    {'environ': {'QUERY_STRING': ''
    REQUEST_METHOD': 'POST'
    CONTENT_TYPE': 'application/json'
    CONTENT_LENGTH': '126'
    REQUEST_URI': '/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1'
    PATH_INFO': '/report/generate/DEMO_TECH_DEMO1'
    DOCUMENT_ROOT': '/usr/share/nginx/html'
    SERVER_PROTOCOL': 'HTTP/1.1'
    REQUEST_SCHEME': 'http'
    REMOTE_ADDR': '192.168.69.16'
    REMOTE_PORT': '54436'
    SERVER_PORT': '80'
    SERVER_NAME': 'lsdev01'
    HTTP_HOST': 'lsdev01'
    HTTP_CONNECTION': 'keep-alive'
    HTTP_CONTENT_LENGTH': '126'
    HTTP_PRAGMA': 'no-cache'
    HTTP_CACHE_CONTROL': 'no-cache'
    HTTP_ACCEPT': 'application/json, text/plain, */*'
    
    HTTP_ORIGIN': 'http://localhost:4213'
    
    HTTP_AUTHORIZATION': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MzQ0OTM4MDksInN1YiI6eyIkJFVTUklETE9HSU4iOiIxNDQ5IiwiJCRVU1JOQU1FTE9HSU4iOiI5OSAtIHdlaXRlcmUgRmFjaGdydXBwZW4iLCIkJFVTUkNPREVMT0dJTiI6IkRXRSIsIiQkU0VTU0lPTkxPR0lEIjoxLCIkJFNJVEVJRCI6IjkwMDAwMDMyNzAiLCIkJFNJVEVHUlAiOiJMQUJPIiwiJCRURVNURkVBVFVSRUxJU1QiOiJURVNUUkVGTkVXXHUwMDFiTVVMVElERUJcdTAwMWJSRVRSSUVWRU5FV1x1MDAxYlJFU1JFRlx1MDAxYkxYUkJBQzJcdTAwMWJGQ1RURVNUXHUwMDFiQ09NVEVTVFx1MDAxYk5PTkVVTklRVUVCQ1x1MDAxYlBFUkZfTFhURVhUIiwiJCRMQU5HVUFHRSI6IiIsIkxBTkdVQUdFIjpudWxsfSwiZXhwIjoxNTM0NTgwMjA5LCJpbnN0YW5jZSI6ImRldiJ9.33Pid_GDPP6LUgoGzv_uU26QisBJNqoqsc7uTczdLvU'
    HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    HTTP_CONTENT_TYPE': 'application/json'
    HTTP_REFERER': 'http://localhost:4213/login'
    HTTP_ACCEPT_ENCODING': 'gzip, deflate'
    HTTP_ACCEPT_LANGUAGE': 'de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7,fr;q=0.6'
    SCRIPT_NAME': '/lx/ui_api/dev/dwe/dwe/reporting'
    wsgi.input': <uwsgi._Input object at 0x7fd792236300>
    wsgi.version': (1, 0)
    wsgi.errors': <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'>
    wsgi.run_once': False
    wsgi.multithread': True
    wsgi.multiprocess': False
    wsgi.url_scheme': 'http'
    uwsgi.version': b'2.0.15'
    uwsgi.core': 3
    uwsgi.node': b'lsdev01'
    werkzeug.request': <Request 'http://lsdev01/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1' [POST]>}
    shallow': False
    view_args': {'reportCode': 'DEMO_TECH_DEMO1'}
    url_rule': <Rule '/report/generate/<reportCode>' (OPTIONS, POST) -> report_generate>
    _parsed_content_type': ('application/json', {})
    stream': <werkzeug.wsgi.LimitedStream object at 0x7fd78f7d7438>
    _cached_data': b'{"mimetype":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","input":{"header":"Test 1","footer":"Test 2"}}'
    _cached_json': {'mimetype': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    input': {'header': 'Test 1'
    footer': 'Test 2'}}
    url': 'http://lsdev01/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1'}
    

    <Request 'http://lsdev01/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1' [POST]>
    {'environ': {'QUERY_STRING': ''
    REQUEST_METHOD': 'POST'
    CONTENT_TYPE': 'application/json'
    CONTENT_LENGTH': '126'
    REQUEST_URI': '/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1'
    PATH_INFO': '/report/generate/DEMO_TECH_DEMO1'
    DOCUMENT_ROOT': '/usr/share/nginx/html'
    SERVER_PROTOCOL': 'HTTP/1.1'
    REQUEST_SCHEME': 'http'
    REMOTE_ADDR': '192.168.69.18'
    REMOTE_PORT': '55154'
    SERVER_PORT': '80'
    SERVER_NAME': 'lsdev01'
    HTTP_HOST': 'lsdev01'
    HTTP_ACCEPT_ENCODING': 'deflate, gzip'
    
    
    
    HTTP_ACCEPT': 'application/json, text/plain, */*'
    HTTP_REFERER': 'http://localhost:4213/login'
    HTTP_ORIGIN': 'http://localhost:4213'
    HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
    HTTP_AUTHORIZATION': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MzQ0OTM4MDksInN1YiI6eyIkJFVTUklETE9HSU4iOiIxNDQ5IiwiJCRVU1JOQU1FTE9HSU4iOiI5OSAtIHdlaXRlcmUgRmFjaGdydXBwZW4iLCIkJFVTUkNPREVMT0dJTiI6IkRXRSIsIiQkU0VTU0lPTkxPR0lEIjoxLCIkJFNJVEVJRCI6IjkwMDAwMDMyNzAiLCIkJFNJVEVHUlAiOiJMQUJPIiwiJCRURVNURkVBVFVSRUxJU1QiOiJURVNUUkVGTkVXXHUwMDFiTVVMVElERUJcdTAwMWJSRVRSSUVWRU5FV1x1MDAxYlJFU1JFRlx1MDAxYkxYUkJBQzJcdTAwMWJGQ1RURVNUXHUwMDFiQ09NVEVTVFx1MDAxYk5PTkVVTklRVUVCQ1x1MDAxYlBFUkZfTFhURVhUIiwiJCRMQU5HVUFHRSI6IiIsIkxBTkdVQUdFIjpudWxsfSwiZXhwIjoxNTM0NTgwMjA5LCJpbnN0YW5jZSI6ImRldiJ9.33Pid_GDPP6LUgoGzv_uU26QisBJNqoqsc7uTczdLvU'
    
    HTTP_CONTENT_TYPE': 'application/json'
    HTTP_CONTENT_LENGTH': '126'
    
    
    SCRIPT_NAME': '/lx/ui_api/dev/dwe/dwe/reporting'
    wsgi.input': <uwsgi._Input object at 0x7fd792236300>
    wsgi.version': (1, 0)
    wsgi.errors': <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'>
    wsgi.run_once': False
    wsgi.multithread': True
    wsgi.multiprocess': False
    wsgi.url_scheme': 'http'
    uwsgi.version': b'2.0.15'
    uwsgi.core': 0
    uwsgi.node': b'lsdev01'
    werkzeug.request': <Request 'http://lsdev01/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1' [POST]>}
    shallow': False
    view_args': {'reportCode': 'DEMO_TECH_DEMO1'}
    url_rule': <Rule '/report/generate/<reportCode>' (OPTIONS, POST) -> report_generate>
    _parsed_content_type': ('application/json', {})
    stream': <werkzeug.wsgi.LimitedStream object at 0x7fd78f7bcf98>
    _cached_data': b'{"mimetype":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","input":{"header":"Test 1","footer":"Test 2"}}'
    _cached_json': {'mimetype': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    input': {'header': 'Test 1'
    footer': 'Test 2'}}
    url': 'http://lsdev01/lx/ui_api/dev/dwe/dwe/reporting/report/generate/DEMO_TECH_DEMO1'}
    

    diff

    但没什么特别的。。。

    编辑:我也试过发送文件,但我有同样的问题。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Denny Weinberg    6 年前

    该死的!!我得到了它!

    我在服务器端编码为base64:

    return Response(base64.b64encode(output), mimetype=mimetype)
    

      download(mimetype, data) {
    
        function s2ab(s) {
          var buf = new ArrayBuffer(s.length);
          var view = new Uint8Array(buf);
          for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
          return buf;
        }
    
        var blob = new Blob([s2ab(atob(data))], {type: mimetype});
        var objectUrl = URL.createObjectURL(blob);
        window.open(objectUrl);
      }
    

    atob=解码base64编码字符串 s2ab=blob的字符串到数组缓冲区

    推荐文章