zoukankan      html  css  js  c++  java
  • 模拟POST上传文件

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

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

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

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

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

      二、换行都是" "

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

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

      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 = "
    ";
     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的一个第三方库,用起来非常方便,代码如下:

     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/

  • 相关阅读:
    C# 使用NPlot绘图技巧
    jsp页面必填项如何加红星号*
    org.mybatis.spring.mapper.MapperScannerConfigurer 类作用
    mybatis对java自定义注解的使用——入门篇
    1.报表TIBCO Jaspersoft Studio工具教程入门--生成jrxml和jasper文件 然后拖拽到项目中 跟ireport一样
    eclipse安装weblogic Server服务器
    创建一个java项目并部署到weblogic服务器
    weblogicjsp编译:查看编译后的java中间代码
    html标签的target属性应用
    5.把报表集成到Web应用程序中-生成网页和导出两种方式
  • 原文地址:https://www.cnblogs.com/pasion-forever/p/3975862.html
Copyright © 2011-2022 走看看