| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 175 人关注过本帖, 1 人收藏
标题:如何用vfp以form-data格式上传图片文件到微信服务器
只看楼主 加入收藏
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:842
专家分:1296
注 册:2021-10-13
结帖率:97.14%
收藏(1)
已结贴  问题点数:20 回复次数:2 
如何用vfp以form-data格式上传图片文件到微信服务器
最近在整合微信的一个素材库的vfp访问类,以便做到素材的获取,上传和下载,准备分享给各位狐友。
可惜现在遇到一个瓶颈,微信API接口要求以form-data的格式向api接口post数据,网上搜索了很多文章都是其他有语言的,不是很看得懂,不知其所以然。
论坛里有没有对此理解比较深刻的狐友?可以帮我解释一下form-data的格式?

下面是我网上搜到的对multipart/form-data请求体的布局说明:

# 请求头 - 这个是必须的,需要指定Content-Type为multipart/form-data,指定唯一边界值
Content-Type: multipart/form-data; boundary=${Boundary}
 
# 请求体
--${Boundary}
Content-Disposition: form-data; name="name of file"
Content-Type: application/octet-stream
 
bytes of file
--${Boundary}
Content-Disposition: form-data; name="name of pdf"; filename="pdf-file.pdf"
Content-Type: application/octet-stream
 
bytes of pdf file
--${Boundary}
Content-Disposition: form-data; name="key"
Content-Type: text/plain;charset=UTF-8
 
text encoded in UTF-8
--${Boundary}--

媒体类型multipart/form-data相对于其他媒体类型如application/x-www-form-urlencoded等来说,最明显的不同点是:

请求头的Content-Type属性除了指定为multipart/form-data,还需要定义boundary参数
请求体中的请求行数据是由多部分组成,boundary参数的值模式--${Boundary}用于分隔每个独立的分部
每个部分必须存在请求头Content-Disposition: form-data; name="${PART_NAME}";,这里的${PART_NAME}需要进行URL编码,另外filename字段可以使用,用于表示文件的名称,但是其约束性比name属性低(因为并不确认本地文件是否可用或者是否有异议)
每个部分可以单独定义Content-Type和该部分的数据体
请求体以boundary参数的值模式--${Boundary}--作为结束标志
每个--${Boundary}之前默认强制必须为CRLF,如果某一个部分的文本类型请求体以CRLF结尾,那么在请求体的二级制格式上,必须显式存在两个CRLF,如果某一个部分的请求体不以CRLF结尾,可以只存在一个CRLF,这两种情况分别称为分隔符的显式类型和隐式类型,说的比较抽象。

*****这里的CRLF,对应与VFP是不是CHR(10)+CHR(13)??? 我就是这样理解的,应该不是chr(13)吧?

微信api接口说明如下:

上传图文消息内的图片获取URL
本接口所上传的图片不占用公众号的素材库中图片数量的100000个的限制。图片仅支持jpg/png格式,大小必须在1MB以下。

接口调用请求说明

http请求方式: POST,https协议 https://api.weixin. 调用示例(使用curl命令,用FORM表单方式上传一个图片): curl -F media=@test.jpg "https://api.weixin.

参数说明

参数            是否必须      说明
access_token               调用接口凭证
media                       form-data中媒体文件标识,有filename、filelength、content-type等信息

*****这里的参数media,它的值是不是就是上面的请求体?
请求体显然不是通过url传递的,应该不是在网址后加?access_token=ACCESS_TOKEN&media=***请求体***来传递的
而是以xmlhttp.send("***请求体***")来传递的,对吧?那上面那个media参数应该如何传递呢?

我的请求体是这样的:

content-type: multipart/form-data; boundary=designed by Sam Jiang(这里有一个chr(10)+chr(13))
--designed by Sam Jiang(这里有一个chr(10)+chr(13))
Content-Disposition: form-data;name="media";filename="/A.JPG";filelength=19930(这里有一个chr(10)+chr(13))
Content-Type: image/jpeg(这里有一个chr(10)+chr(13))&&Content-Type: applicatin/octet-stream 换这个也不行。
<这里是图片的二进制字符串>(这里有一个chr(10)+chr(13))
--designed by Sam Jiang--(这里有一个chr(10)+chr(13))

微信api接口返回的的错误是:
{"errcode":41005,"errmsg":"media data missing hint: [GdNTya0295w487] rid: 677a44f7-6fdd831b-3d684604"}

调试了很久,不知道到底错在哪里。。。

好累
搜索更多相关主题的帖子: name 请求 格式 接口 media 
2025-01-05 16:40
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:842
专家分:1296
注 册:2021-10-13
收藏
得分:0 
网上的代码做参考,我参考了他的代码
程序代码:
    /**
     * 上传图文消息内的图片获取URL
     * http请求方式: POST,https协议  以表单形式提交
     * https://api.weixin.*/
    @Test
    public void test6(){
        String redisToken = wxService.getRedisToken();
        String urlStr = "https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN";
        String replaceUrl = urlStr.replace("ACCESS_TOKEN", redisToken);
        File file = new File("/Users/LiuShihao/IdeaProjects/wxthepublic/FtA17e_zIAqlFyfOZ-tpkbhPmZFQ-EIKGef4NwwPfNaPqGARTs4eX7yrX8gAV5Mv.jpg");
        StringBuilder resp = new StringBuilder();
        String result=null;
        try {
            URL urlObj = new URL(replaceUrl);
            HttpsURLConnection conn = (HttpsURLConnection) urlObj.openConnection();
            conn.setRequestMethod("POST");//以POST方式提交表单
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestProperty("Connection","Keep-Alive");
            conn.setRequestProperty("Charset","UTF-8");
            //数据边界
            String boundary = "----------"+System.currentTimeMillis();
            conn.setRequestProperty("Content-Type","multipart/form-data; boundary="+boundary);
            //获取输出流
            OutputStream out = conn.getOutputStream();
            //创建文件输入流
            FileInputStream fis = new FileInputStream(file);
            StringBuilder sb = new StringBuilder();
            sb.append("--");
            sb.append(boundary);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"media\"; filename=\""+file.getName()+"\"\r\n");
            sb.append("Content-Type: applicatin/octet-stream\r\n\r\n");
            out.write(sb.toString().getBytes());

            byte[] bytes = new byte[1024];
            int len;
            while((len = fis.read(bytes)) != -1){
                out.write(bytes,0,len);
            }
            String foot = "\r\n--"+boundary+"--\r\n";
            out.write(foot.getBytes());
            out.flush();
            out.close();
            //读取数据
            if(HttpsURLConnection.HTTP_OK==conn.getResponseCode()){

                StringBuffer strbuffer=null;
                BufferedReader reader=null;
                try {
                    strbuffer=new StringBuffer();
                    reader=new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    String lineString=null;
                    while((lineString=reader.readLine())!=null){
                        strbuffer.append(lineString);
                    }
                    result=strbuffer.toString();
                } catch (IOException e) {
                    System.out.println("发送POST请求出现异常!"+e);
                    e.printStackTrace();
                }finally{
                    if(reader!=null){
                        reader.close();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        //resp:{"url":"http:\/\/mmbiz.\/mmbiz_jpg\/OsaJQib8ibD8ActRfkHSkvZsntjEjmicVGibcWic0Kbkq8pgnf4BJgytEOUBxmlIM1IBCPsWLOXUW0dUwAZziaiajwNfw\/0"}
        //http://mmbiz./mmbiz_jpg/OsaJQib8ibD8ActRfkHSkvZsntjEjmicVGibcWic0Kbkq8pgnf4BJgytEOUBxmlIM1IBCPsWLOXUW0dUwAZziaiajwNfw/0
    }
2025-01-05 16:43
wcx_cc
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:52
帖 子:401
专家分:1287
注 册:2015-10-2
收藏
得分:20 
参考一段 C# 的看看有没有用
string url = report_addr +$"thirdApi/saveHealthExamPile":
NameValueCollection nvc = new NameValueCollection ();
nve.Add("param,“{\“idNo\ :\  + sfzh + “\’,\"examDate\":\"" + tjb. Jdrq. Value. ToString("yyyy-M-dd) + "\, \"type\":\"5\}"):
var task = uploadGXTJ(lt.nvc,ms. ToArray(),url,partner_license):
async
Task<qmResult>
uploadGXTJ
LoginToken
lt.
NameValueCollection formData,
byte[]
file.
string url,
string partner_license)
try
using(HttpClient webClient = new HttpClient())
// 添加表单数据
//webClient.Headers.Add("Content-Type","multipart/form-data");
webClient. DefaultRequestHeaders.AcceptEncoding. Add(new StringWithQualityHeaderValue("utf-8"));
webClient. DefaultRequestHeaders.Add("access_token", lt.access_token);
webClient. DefaultRequestHeaders.Add("partner-license", partner_license);

using (var mformData = new MultipartFormDataContent ()

var fileContent = new StreamContent(new MemoryStream

fileContent.Headers.ContentType = MediaTypeHeaderValue. Parse("multipart/form-data");

mformData.Add(fileContent,“file", Path.GetFileName("mn.jpg"));

foreach (var key in formData.AllKeys)
var keyValueContent = new StringContent(formData[key]):
mformData.Add (keyValueContent, key): // 替换为你的表单键名
2025-01-06 00:00
快速回复:如何用vfp以form-data格式上传图片文件到微信服务器
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028152 second(s), 10 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved