【问题标题】:Azure http-trigger function to query HTTP POST request with multipart/form-dataAzure http-trigger 函数使用 multipart/form-data 查询 HTTP POST 请求
【发布时间】:2020-11-18 03:24:12
【问题描述】:

我正在使用带有 C#(或 NodeJS)的 Azure 函数应用程序。如何编写http post请求来完成以下任务?

  1. Http 触发函数应用应向其他服务器发送 HTTP 请求以获取一些数据。
  2. 读取传入响应并由 http 触发器源作为 JSON 文件发回。

我是 Azure 功能的新手,您的支持将非常有帮助。

例如

网址:https://postman-echo.com/post

HTTP 的标头:

Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: Keep-Alive
Content-Length: 1330
Content-Type: multipart/form-data;boundary=XXXXabcXXXX
Keep-Alive: timeout=30000
Transfer-Encoding: chunked

HTTP 正文:

--XXXXabcXXXX
Content-Disposition: form-data; name="RequestData"
Content-Type: application/JSON; charset=utf-8
Content-Transfer-Encoding: 8bit

{
    "cmdDict":
        {
        "application":"b",
        "application_session_id":"cd"
        },
    "appId": "123",
    "uId":"345645"
}
--XXXXabcXXXX
Content-Disposition : form-data; name="Parameter"; paramName="REQUEST_INFO"
Content-Type: application/json; charset=utf-8
Content-Transfer-Encoding: 8bit

{
"abc":
  {"x":"default",
   "y":[],
   "message":"HELLO WORLD"
  },
"D":1
}
--XXXXabcXXXX--

【问题讨论】:

    标签: javascript c# node.js http azure-functions


    【解决方案1】:

    这是在 Azure Functions 中使用 Node.js 执行 multipart/form-data 请求的方法。

    您需要安装的唯一依赖项是来自 npm 的 form-data

    const https = require('https')
    const FormData = require('form-data')
    
    const host = 'postman-echo.com'
    const path = '/post'
    const method = 'POST'
    const requestHeaders = {
      Accept: '*/*',
      // add headers here as necessary
    }
    const parts = [
      {
        name: 'RequestData',
        data: {
          cmdDict: {
            application: 'b',
            application_session_id: 'cd',
          },
          appId: '123',
          uId: '345645',
        },
        contentType: 'application/json; charset=utf-8',
      },
      {
        name: 'Parameter',
        data: {
          abc: { x: 'default', y: [], message: 'HELLO WORLD' },
          D: 1,
        },
        contentType: 'application/json; charset=utf-8',
      },
    ]
    
    async function fetchFromOrigin() {
      return new Promise((resolve, reject) => {
        const form = new FormData()
    
        parts.forEach((part) =>
          form.append(part.name, JSON.stringify(part.data), {
            contentType: part.contentType,
          }),
        )
    
        const options = {
          host,
          path,
          method,
          headers: Object.assign({}, requestHeaders, form.getHeaders()),
        }
    
        const req = https.request(options, (res) => {
          if (res.statusCode < 200 || res.statusCode > 299) {
            return reject(new Error(`HTTP status code ${res.statusCode}`))
          }
    
          const body = []
          res.on('data', (chunk) => body.push(chunk))
          res.on('end', () => {
            const resString = Buffer.concat(body).toString()
            resolve(resString)
          })
        })
    
        req.on('error', (err) => reject(new Error(err.message)))
        form.pipe(req)
      })
    }
    
    module.exports = async function (context, req) {
      const res = await fetchFromOrigin()
    
      context.res = {
        body: res,
      }
    }
    

    【讨论】:

    • 太棒了!它就像一个魅力。我只需要调整名称:name='Parameter; paramName=REQUEST_INFO' 因为库中没有 paramName。非常感谢!
    【解决方案2】:

    请参考这段代码:

    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System;
    
    namespace FunctionMultipart
    {
        public static class Function1
        {
            [FunctionName("Function1")]
            public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
                ILogger log)
            {
                log.LogInformation("C# HTTP trigger function processed a request.");
    
                HttpClient _httpClient = new HttpClient();
    
                string URL = "https://postman-echo.com/post";
                using (var multiPartStream = new MultipartFormDataContent("XXXXabcXXXX"))
                {
                    StringContent jsonPart1 = new StringContent("{\"cmdDict\": {\"application\":\"b\",\"application_session_id\":\"cd\"},\"appId\": \"123\",\"uId\":\"345645\"}");
                    jsonPart1.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
                    jsonPart1.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    
                    StringContent jsonPart2 = new StringContent("{\"abc\":{\"x\":\"default\",\"y\":[],\"message\":\"HELLO WORLD\"},\"D\":1}");
                    jsonPart2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data");
                    jsonPart2.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    
                    multiPartStream.Add(jsonPart1, "RequestData");
                    multiPartStream.Add(jsonPart2, "Parameter");
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URL);
                    request.Content = multiPartStream;
                    //"application/json" - content type
                    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                    request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
                    request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
                    request.Headers.Connection.Add("Keep-Alive");
                    //request.Headers.Add("Content-Length", "1330");
                    //request.Headers.Add("Content-Type", "multipart/form-data;boundary=XXXXabcXXXX");
    
                    HttpCompletionOption option = HttpCompletionOption.ResponseContentRead;
                    System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
                    
                    using (HttpResponseMessage response = _httpClient.SendAsync(request, option).Result)
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            String result = response.Content.ReadAsStringAsync().Result;
                            //var deserializedObject = JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result);
                            //return deserializedObject.ToString();
                            log.LogInformation(result);
                        }
                    }
    
                }
    
                return new OkObjectResult("ok");
            }
        }
    }
    

    【讨论】:

    • 嘿,非常感谢您的回复。这很棒!但是,当我使用webhook.site 收听我的请求时,我看到消息正文 jsonPart1 和 jsonPart2 在消息正文中没有。你知道可能缺少什么吗?
    猜你喜欢
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2014-05-13
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    相关资源
    最近更新 更多