码迷,mamicode.com
首页 > 其他好文 > 详细

模拟POST上传文件

时间:2014-09-16 22:05:01      阅读:317      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   java   ar   for   

  上传下载文件在浏览器里面都非常简单,上传文件在浏览器里就是几个标签,中间到底发生了什么我们全然不知,而下载文件更是简单——下载文件只需获得文件的地址以二进制的方式写出来就好。最近有个同学想在安卓里面做一个上传功能的App,最简单的莫过于HTTP的POST方法了(fork this  https://www.imququ.com/post/four-ways-to-post-data-in-http.html)。

  可以先观察下上传文件的HTTP Header:

bubuko.com,布布扣

可以看到Request Header后面多了一个没有见过的 Request Payload, 这个Request Payload 正是上传文件的关键,我的理解主要参考 http://jackface.iteye.com/blog/2098604,这篇文章详细的介绍了他在后台抓取到的POST的信息的格式,对,POST传送文件的时候格式一定要严格,否则就上传不了(我已经做过多次试验),文章里抓到的数据和 Request Payload里的数据差不多,知识Payload里面没有文件的二进制流。

  总结一下,POST上传文件的要点:   

  一、boundary是浏览器随机生成的分隔符(请求头里面有),请求头里面的boundary前面是四个"-",而Payload里面的是六个,多的两个叫做 prefix(前缀),然后就是结束的地方又有两个prefix(怎么感觉应该叫做后缀)

  二、换行都是"\r\n"

  三、只有最后结束的地方才会多一个前缀,如果是多个文件上传,前面的都一样只有最后一个会多一个前缀

附java实现代码(照着网上的改的):

bubuko.com,布布扣
  1 import java.io.ByteArrayOutputStream;
  2 import java.io.File;
  3 import java.io.FileInputStream;
  4 import java.io.FileNotFoundException;
  5 import java.io.IOException;
  6 import java.io.InputStream;
  7 import java.io.OutputStream;
  8 import java.net.HttpURLConnection;
  9 import java.net.MalformedURLException;
 10 import java.net.URL;
 11 
 12 public class Poster
 13 {
 14   static String boundary = "--------------7d226f700d0";
 15   static String prefix = "--";
 16   static String newLine = "\r\n";
 17   public static void main(String args[])
 18   {
 19     test();
 20   }
 21   private static void test()
 22   {
 23     try
 24     {
 25       
 26       URL url = new URL("http://1.crackme.sinaapp.com/scripts/upload.php");//post address
 27       HttpURLConnection connection = (HttpURLConnection) url.openConnection();
 28       connection.setDoInput(true);
 29       connection.setDoOutput(true);
 30 
 31       connection.setRequestProperty("Content-type","multipart/form-data;boundary="+boundary); 
 32       AssemblyHttp(connection.getOutputStream());
 33       InputStream ins = connection.getInputStream();
 34       byte[] b = readBuffer(ins);
 35       System.out.println(new String(b));
 36     } catch (MalformedURLException e)
 37     {
 38       System.out.println(" URL address error ");
 39     } catch (IOException e)
 40     {
 41       System.out.println(" URL open error ");
 42     }
 43   }
 44   private static void AssemblyHttp(OutputStream out)
 45   {
 46     StringBuffer params = new StringBuffer();
 47       
 48     params.append(prefix+boundary + newLine);
 49                                                   //name is the the key "name"‘s value in the upload form
 50     params.append("Content-Disposition: form-data; name=\"myfile[]\";filename="+"\"20140821182141.jpg\"");
 51     params.append(newLine);       
 52     params.append("Content-Type: image/jpeg");
 53     params.append(newLine+newLine);
 54     
 55     StringBuffer params2 = new StringBuffer();
 56       
 57     params2.append(prefix+boundary + newLine);
 58                                                                 
 59     params2.append("Content-Disposition: form-data; name=\"myfile[]\";filename="+"\"6b68a43308f198a375d9369a39c7ee1e.jpg\"");
 60     params2.append(newLine);       
 61     params2.append("Content-Type: image/jpeg");
 62     params2.append(newLine+newLine);
 63 
 64 
 65     File file = new File("C:\\Users\\KL\\Pictures\\20140821182141.jpg");
 66     File file2 = new File("C:\\Users\\KL\\Pictures\\6b68a43308f198a375d9369a39c7ee1e.jpg");
 67     try
 68     {
 69       InputStream in = new FileInputStream(file);
 70       out.write(params.toString().getBytes());                   
 71       out.write(readBuffer(in));
 72       out.write(newLine.getBytes());           
 73       out.write((prefix+boundary+newLine).getBytes());
 74 
 75 
 76       InputStream in2 = new FileInputStream(file2);
 77       out.write(params2.toString().getBytes());                   
 78       out.write(readBuffer(in2));
 79       out.write(newLine.getBytes());
 80 
 81       out.write((prefix+boundary + prefix).getBytes());
 82       out.flush();
 83       out.close();         
 84     } catch (FileNotFoundException e)
 85     {
 86       System.out.println(" file not found  ");
 87     } catch (IOException e)
 88     {
 89       System.out.println(" IO Error ");
 90     }
 91   }
 92 
 93 
 94   public static byte[] readBuffer(InputStream ins) throws IOException
 95   {
 96     byte b[] = new byte[1024];
 97     ByteArrayOutputStream stream = new ByteArrayOutputStream();
 98     int len = 0;
 99     while((len=ins.read(b))!= -1)
100     {
101       stream.write(b, 0, len);
102     }
103     return stream.toByteArray();
104   }
105 }
View Code

 

用java写可以看到好多上传的细节,用Python的第三方库就非常简洁了,libcurl(fork this http://curl.haxx.se/libcurl/)有python的移植但是有点太庞大的,配置起来也不好配置,poster 也是python的一个第三方库,用起来非常方便,代码如下:

bubuko.com,布布扣
 1 # test_client.py
 2 from poster.encode import multipart_encode
 3 from poster.streaminghttp import register_openers
 4 import urllib2
 5 
 6 url = ["http://1.crackme.sinaapp.com/scripts/upload.php","http://localhost/learnPHP/scripts/upload.php"]
 7 
 8 register_openers()
 9 
10 
11 datagen, headers = multipart_encode({"myfile": open("C:\\Users\\KL\\Pictures\\20140821182141.jpg", "rb")})
12 
13 
14 request = urllib2.Request(url[0], datagen, headers)
15 
16 print urllib2.urlopen(request).read()
View Code

(fork this http://alexliyu.blog.163.com/blog/static/162754496201252154412432/

模拟POST上传文件

标签:style   blog   http   color   io   os   java   ar   for   

原文地址:http://www.cnblogs.com/pasion-forever/p/3975862.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!