chttppost文件上传
1. C++Builder XE2怎么通过IDHTTP的POST方法上传文件
C++Builder XE2如何通过IDHTTP的POST方法上传文件?
DEPHI的代码如下:
var
MultiPartFormDataStream: TMsMultiPartFormDataStream;
idhttp1:TIdHTTP;
begin
MultiPartFormDataStream := TMsMultiPartFormDataStream.Create;
try
id(nil);
IdHTTP1.ProtocolVersion:=pv1_1;
IdHTTP1.HandleRedirects := True;
IdHTTP1.Request.UserAgent:='Klive';
IdHTTP1.Request.Connection:='Keep-Alive';
IdHTTP1.HTTPOptions:=IdHTTP1.HTTPOptions+[hoKeepOrigProtocol];
IdHttp1.Request.ContentType := MultiPartFormDataStream.RequestContentType;
MultiPartFormDataStream.AddFormField('name', 'file');
MultiPartFormDataStream.AddFormField('filename', Path);
MultiPartFormDataStream.AddFile('file', filename, 'testmime');
MultiPartFormDataStream.PrepareStreamForDispatch;
MultiPartFormDataStream.Position := 0;
try
Result:=pchar(id(str,MultiPartFormDataStream));
except
on e: EIdHTTPProtocolException do
begin
result:= pchar(e.ErrorMessage);// Application.MessageBox(PChar(e.ErrorMessage), 'ERROR', MB_OK + MB_ICONSTOP);
end;
end;
finally
MultiPartFormDataStream.Free;
这个代码是金山快盘上传文件的实现代码,具体要求是这样的:
POST /cdlnode/1/fileops/upload_file oauth_nonce=57895862&oauth_timestamp=1328956550&oauth_consumer_key=xcKXXgo9AkXdJuBn&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_token=&oauth_signature=eQ9BhjCaIpUAWDD3cbb%2BrtlfXt4%3D&path=%2Fttt1328956550.95sss%2Ftestw.wps&root=app_folder&overwrite=True HTTP/1.1
Accept-Encoding: identity
Content-Length: 237
Host: ufaclien
Content-Type: multipart/form-data; boundary=----------ThIs_Is_tHe_bouNdaRY_$
Connection: close
User-Agent: klive
------------ThIs_Is_tHe_bouNdaRY_$
Content-Disposition: form-data; name="file"; filename="testw.wps"
Content-Type: application/octet-stream
1328956550.991328956550.991328956550.991328956550.99
------------ThIs_Is_tHe_bouNdaRY_$--
2. http方式上传数据Post时,对数据有什么格式要求吗
Http之Get/Post请求区别
1.HTTP请求格式:
<request line>
<headers>
<blank line>
[<request-body>]
在HTTP请求中,第一行必须是一个请求行(request line),用来说明请求类型、要访问的资源以及使用的HTTP版本。紧接着是一个首部(header)小节,用来说明服务器要使用的附加信息。在首部之后是一个空行,再此之后可以添加任意的其他数据[称之为主体(body)]。
1. get是从服务器上获取数据,post是向服务器传送数据。
get 和 post只是一种传递数据的方式,get也可以把数据传到服务器,他们的本质都是发送请求和接收结果。只是组织格式和数据量上面有差别,http协议里面有介绍
2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
因为get设计成传输小数据,而且最好是不修改服务器的数据,所以浏览器一般都在地址栏里面可以看到,但post一般都用来传递大数据,或比较隐私的数据,所以在地址栏看不到,能不能看到不是协议规定,是浏览器规定的。
3. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
没明白,怎么获得变量和你的服务器有关,和get或post无关,服务器都对这些请求做了封装
4. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
post基本没有限制,我想大家都上传过文件,都是用post方式的。只不过要修改form里面的那个type参数
5. get安全性非常低,post安全性较高。
如果没有加密,他们安全级别都是一样的,随便一个监听器都可以把所有的数据监听到,不信你自己下一个监听网络资源的软件,
Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求,在FORM(表单)中,Method默认为"GET",实质上,GET和POST只是发送机制不同,并不是一个取一个发!
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
1.根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。
(1).所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。
3. Android中使用HttpPost实现数据与文件同时上传的功能
第一步:编写一个Servlet,把接收到的HTTP信息保存在一个文件中,代码如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取输入流,是HTTP协议中的实体内容
ServletInputStream sis=request.getInputStream();
//缓冲区
byte buffer[]=new byte[1024];
FileOutputStream fos=new FileOutputStream("d://file.log");
int len=sis.read(buffer, 0, 1024);
//把流里的信息循环读入到file.log文件中
while( len!=-1 )
{
fos.write(buffer, 0, len);
len=sis.readLine(buffer, 0, 1024);
}
fos.close();
sis.close();
}
第二步:实现如下图1的的表单页面,生成一个注册表单,提交到Servlet中
详细的代码如下:
<form action="servlet/ReceiveFile" method="post" enctype="multipart/form-data">
第一个参数<input type="text" name="name1"/> <br/>
第二个参数<input type="text" name="name2"/> <br/>
第一个上传的文件<input type="file" name="file1"/> <br/>
第二个上传的文件<input type="file" name="file2"/> <br/>
<input type="submit" value="提交">
</form>
注意了,由于要上传附件,所以一定要设置enctype为multipart/form-data,才可以实现附件的上传。
第三步:填写完信息后按“提交”按钮后,在D盘下查找file.log文件用记事本打开,数据如下:
-----------------------------7d92221b604bc
Content-Disposition: form-data; name="name1"
hello
-----------------------------7d92221b604bc
Content-Disposition: form-data; name="name2"
world
-----------------------------7d92221b604bc
Content-Disposition: form-data; name="file1"; filename="C:/2.GIF"
Content-Type: image/gif
GIF89a
4. HTTP 的 POST 参数提交和上传的不同与 Mojolicious 的实现
对于 HTTP 协议, 我们在使用 POST 上传的时候, 其实是有好几种不同的处理方式的, 所以对于客户端和服务器端, 也分别都有不同的处理. 正常普通的网页在提交参数上传到服务器的时候, 主要会根据内容的不同来使用不同的处理. 所体现在不同的地方在 Content-Type 的类型.
比如我们常常用 Mojolicious 处理这类接收到的参数和内容的时候, 会让很多人晕掉, 所以我在这, 基于协议的头, 来给大家介绍一下在参数和上传的时候有什么不同.
客户端, 比如浏览器网页中的 form 的表格的参数的不同, 客户端比如 linux 命令行的 curl 的参数的不同和程序接口提交参数的不同, HTTP 协议在上传的时候, 大约会有三种不同, 这些体现在 Content-Type 的三种类型:
application/x-www-form-urlencoded
multipart/form-data
post 的 body 的内容
下面我们来详细介绍
1. application/x-www-form-urlencoded 默认
浏览器: 在 HTML 中 form 有个参数是 enctype 属性用于指定编码方式, 常用有前面讲的两种: application/x-www-form-urlencoded 和 multipart/form-data. 但默认的时候, 我们并不指定. 不指定的时候, 默认是 "application/x-www-form-urlencoded" , 所以其实, 我们平时都是使用的这种格式来提交数据. 因为是默认就不写出来了. 注意, 这个会对空格和特别的符号进行 url 的 encode.
程序: 我们现在以 Mojo::UserAgent 这个模块为例子, 我们提交一个参数 args 值为 test.
$ua->post('ht tp:/ /w ww.php-oa.co m/a/b' => form => { args => 'test'});
命令:
$curl -svo /dev/null -d "args=test" htt p:/ /w ww.php-oa.co m/a/b
HTTP 协议状态
这个时候所发送的 HTTP 的头和内容分别如下. body 中会存着参数, 会有一个特别的 Header.
-- Blocking request (ht tp:/ /w ww.php-oa.co m/a/b)
-- Connect (ht tp:ww w.php-oa.c om:80)
-- Client >>> Server (htt p://w ww.php-oa.c om/a/b)
POST /a/b HTTP/1.1
User-Agent: Mojolicious (Perl)
Connection: keep-alive
Content-Type: application/x-ww w-form-urlencoded
Accept-Encoding: gzip
Content-Length: 9
Host: www.php-oa.com
args=test
服务端接收方式
这个时候, 服务器会根据因为是 POST 的方法, 并且头部的 Content-Type: application/x-www-form-urlencoded 会去解析 body 的参数. 这样在 Mojolicious 服务器
post '/a/b' => sub {
my $self = shift;
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
2. multipart/form-data 大文件, 媒体文件
对于比较大的, 有一些二进制数据和象视频文件之类大文件, 建议使用这种方式上传.
浏览器:
普通的 HTTP 的写法如果要使用 enctype 的话, 只要象下面一样就行.
<form action="/path/to/login" enctype="multipart/form-data">
<input disabled="disabled" name="first_name" type="text" />
<input value="Ok" type="submit" />
</form>
客户端:
在 Mojo::UserAgent 考虑得非常周全, 当你提交的内容中包含二进制文件之类时, 就会自动帮你转换成 "multipart/form-data" 格式提交. 这个格式会生成一个随机字符来分割不同参数. 区分是否使用这种格式主要是, 当你提交的参数中, 又是一个引用, 并且引中可以使用 content 来指定内容或者 file 来指定路径.
$ua->post('htt p:/ /w ww.php-oa.c om/a/b' => form => { args => 'test', args_file => { file => '/root/.bash_history' } });
# or
$ua->post('ht tp://w ww.php-oa.c om/a/b' => form => { args => 'test', args_file => { content => 'test' } });
HTTP 协议状态
这个地方我们可以见到 Content-Type: multipart/form-data 的请求头, 告诉文件和参数是这种格式上传过来的.并且 boundary 用于指定一个参数之间的分割符.
-- Blocking request (ht tp://w ww.php-oa.c om/a/b)
-- Connect (ht tp:w ww.php-oa.co m:80)
-- Client >>> Server (ht p://ww w.php-oa.co m/a/b)
POST /a/b HTTP/1.1
User-Agent: Mojolicious (Perl)
Content-Type: multipart/form-data; boundary=WRoHX
Connection: keep-alive
Accept-Encoding: gzip
Content-Length: 14428
Host: www.php-oa.com
--WRoHX
Content-Disposition: form-data; name="args"
test
--WRoHX
Content-Disposition: form-data; name="args_file"; filename=".bash_history"
........文件本身
服务器接收方式
在后端的服务器接收的时候 Mojolicious 想得非常周到. 对于这种格式能自动解析, 并且全程异步.不会多占内存. 这个会自动给大的文件使用一个叫 Mojo::Upload 的对象来处理, 我们可以通过 $self->req->upload('args_file'); 这个方法取得这个内容的对象, 这个内容的对象是Mojo::Asset::File 这个对象, 存文件和取大文件之类可以直接调用.
post '/a/b' => sub {
my $self = shift;
my $upload = $self->req->upload('args_file');
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
3. POST 的 body 的内容
最后一种, 是有时我们做大文件上传, 和提交内容之类.这个时候, 整个 body 都是文件本体. 参数象 get 一样通过 url 传过去.
这个就不用抓头了, 没任何转换, 直接整个 body 是个大文件.
客户端提交:
我们来看看客户端在这个时候怎么上传送. 同样, 我们使用 Mojo::UserAgent 为例子.
my $ua = Mojo::UserAgent->new;
$ua->transactor->add_generator(stream => sub {
my ($transactor, $tx, $path) = @_;
$tx->req->content->asset(Mojo::Asset::File->new(path => $path));
});
$ua->post('ht tp://w ww.php-oa.co m/a/b' => stream => '/root/.bash_history' );
服务器接收
这个时候, 在服务器端怎么接收啦?
post '/a/b' => sub {
my $self = shift;
my $body = $self->req->body;
my $foo = $self->param('args');
$self->render(text => "Hello from $foo.");
}
这个, 我们直接取请求的 body 就可以了, 但这有个小问题, 这是这个文件上传完, 这个 body 会存着所有的文件, 比如这个上传的文件有 1G , 这个 1G 就都会占着内存. 这个情况, Mojolicious 并没有实现事件来根据块取文件. 晚点, 我有个有于大文件上传的文章, 会分享我在 Mojolicious 中实现异步以块方式存储文件. 这样用户上传多少, 我存多少, 并不会占用更多的内存.
好了整个三种方式都介绍完了, 大家一定注意区分哦 .
5. 怎么用C实现Http POST功能向Http服务器上传文件
用socket就行了。
和服务器建立请求。
然后发送请求报文"\r\n\r\n"结束之后是数据。
post分为,application/x-www-form-urlencoded和multipart/form-data boundary=
要是上传文件,就得使用multipart/form-data boundary=...
服务器那边根据boundary来解析出数据。
6. java客户端通过Http发送POST请求上传文件
要按http的multi-part上传的。接收端,再按multi-part解析成文件流
7. angularjs使用$http post上传文件的时候,怎样获取文件上传的进度
angular在1.5.5以上的版本中,在$http中也加入了eventHandler和uploadEventHandlers等方法,所以可以直接这样写:
$http({
method: 'POST',
url: url,
eventHandlers: {
progress: function(c) {
console.log('Progress -> ' + c);
console.log(c);
}
},
uploadEventHandlers: {
progress: function(e) {
console.log('UploadProgress -> ' + e);
console.log(e);
}
},
data: uploadData,
}).success(function(data) {
console.log(data);
}).error(function(data, status) {
console.log(data);
});
最后,也可以用比较成熟的组件去解决,推荐angular-file-upload
8. 在linux,apache下通过HTTP POST为什么上传不了2G的大文件
这个一般是在php配置文件限制了
php.ini
upload_max_filesize = 2999M
post_max_size = 2999M
memory_limit = 2999M
9. http请求中get和post方式提交的区别
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。
(1).所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET
请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。
* 注意:这里安全的含义仅仅是指是非修改信息。
(2).幂等的意味着对同一URL的多个请求应该返回同样的结果。这里我再解释一下幂等这个概念:
幂等(idempotent、idempotence)是一个数学或计算机学概念,常见于抽象代数中。
幂等有一下几种定义:
对于单目运算,如果一个运算对于在范围内的所有的一个数多次进行该运算所得的结果和进行一次该运算所得的结果是一样的,那么我们就称该运算是幂等的。比如绝对值运算就是一个例子,在实数集中,有abs(a)=abs(abs(a))。
对于双目运算,则要求当参与运算的两个值是等值的情况下,如果满足运算结果与参与运算的两个值相等,则称该运算幂等,如求两个数的最大值的函数,有在在实数集中幂等,即max(x,x)
= x。
看完上述解释后,应该可以理解GET幂等的含义了。
但在实际应用中,以上2条规定并没有这么严格。引用别人文章的例子:比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。从根本上说,如果目标是当用户打开一个链接时,他可以确信从自身的角度来看没有改变资源即可。
2.根据HTTP规范,POST表示可能修改变服务器上的资源的请求。
继续引用上面的例子:还是新闻以网站为例,读者对新闻发表自己的评论应该通过POST实现,因为在评论提交后站点的资源已经不同了,或者说资源被修改了。
上面大概说了一下HTTP规范中GET和POST的一些原理性的问题。但在实际的做的时候,很多人却没有按照HTTP规范去做,导致这个问题的原因有很多,
比如说:
1.很多人贪方便,更新资源时用了GET,因为用POST必须要到FORM(表单),这样会麻烦一点。
2.对资源的增,删,改,查操作,其实都可以通过GET/POST完成,不需要用到PUT和DELETE。
3.另外一个是,早期的Web MVC框架设计者们并没有有意识地将URL当作抽象的资源来看待和设计,所以导致一个比较严重的问题是传统的Web
MVC框架基本上都只支持GET和POST两种HTTP方法,而不支持PUT和DELETE方法。
*
简单解释一下MVC:MVC本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器。使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。
以上3点典型地描述了老一套的风格(没有严格遵守HTTP规范),随着架构的发展,现在出现REST(Representational State
Transfer),一套支持HTTP规范的新风格。
说完原理性的问题,我们再从表面现像上面看看GET和POST的区别:
1.GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
POST把提交的数据则放置在是HTTP包的包体中。
2."GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据,IIS4中最大为80KB,IIS5中为100KB"??!
以上这句是我从其他文章转过来的,其实这样说是错误的,不准确的:
(1).首先是"GET方式提交的数据最多只能是1024字节",因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了。而实际上,URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
注意这是限制是整个URL长度,而不仅仅是你的参数值数据长度。[见参考资料5]
(2).理论上讲,POST是没有大小限制的,HTTP协议规范也没有进行大小限制,说“POST数据量存在80K/100K的大小限制”是不准确的,POST数据是没有限制的,起限制作用的是服务器的处理程序的处理能力。
对于ASP程序,Request对象处理每个表单域时存在100K的数据长度限制。但如果使用Request.BinaryRead则没有这个限制。
由这个延伸出去,对于IIS 6.0,微软出于安全考虑,加大了限制。我们还需要注意:
1).IIS 6.0默认ASP POST数据量最大为200KB,每个表单域限制是100KB。
2).IIS 6.0默认上传文件的最大大小是4MB。
3).IIS 6.0默认最大请求头是16KB。
IIS 6.0之前没有这些限制。[见参考资料5]
所以上面的80K,100K可能只是默认值而已(注:关于IIS4和IIS5的参数,我还没有确认),但肯定是可以自己设置的。由于每个版本的IIS对这些参数的默认值都不一样,具体请参考相关的IIS配置文档。
3.在ASP中,服务端获取GET请求参数用Request.QueryString,获取POST请求参数用Request.Form。在JSP中,用request.getParameter("XXXX")来获取,虽然jsp中也有request.getQueryString()方法,但使用起来比较麻烦,比如:传一个test.jsp?name=hyddd&password=hyddd,用request.getQueryString()得到的是:name=hyddd&password=hyddd。在PHP中,可以用$_GET和$_POST分别获取GET和POST中的数据,而$_REQUEST则可以获取GET和POST两种请求中的数据。值得注意的是,JSP中使用request和PHP中使用$_REQUEST都会有隐患,这个下次再写个文章总结。
4.POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site
request forgery攻击。
总结一下,Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求,在FORM(表单)中,Method默认为"GET",实质上,GET和POST只是发送机制不同,并不是一个取一个发!
10. java客户端通过http发送POST请求上传文件
这样的写法,是直接socket的做法。
如果是HTTP的,要按HTTP的协议进行。先了解一下multi-part的post