HTTP POST 发送JSON格式数据(解决Expect:100-continue 问题)

最近在开发的一个项目,需要涉及到使用Http请求发送比较大的数据,研究了挺长时间,遇到问题,解决问题,在此分享给大家

1.由于数据量较大,所以采用POST方式 传输数据(POST理论上不限制数据大小,但不同服务器都会有相应的默认设置限制数据大小)

2.由于项目需要,使用JSON格式的数据

代码示例:

JAVA 版,使用Apache的commons-httpClient包 发送http请求,代码仅供参考,发送请求方式可根据自己需要进行修改

import org.apache.commons.httpclient.*;
//使用apache commons httpclient
private static final String APPLICATION_JSON = "application/json;charset=uft-8";
private static final String CONTENT_TYPE_TEXT_JSON = "text/json";

/**
* 使用http Post 发送json
* @param url
* @param json 选择自己喜欢的Json包格式化数据
* @throws Exception
*/
public static void httpPostWithJSON(String url, String json) throws Exception {
  // 将JSON进行UTF-8编码,以便传输中文
  String encoderJson = URLEncoder.encode(json, "UTF-8");
   
  HttpClient httpclient = new HttpClient();
  PostMethod method = new PostMethod(url);
  RequestEntity requestEntity = new StringRequestEntity(encoderJson);
  method.setRequestEntity(requestEntity);
  method.addRequestHeader("Content-Type",APPLICATION_JSON);
  int result = httpclient.executeMethod(method);

  System.out.println( "Response status code: " + result);
  System.out.println( "Response body: " );
  System.out.println(method.getResponseBodyAsString());
  method.releaseConnection();
}

PHP版,使用curl,这里要注意:curl 使用POST方式发送请求 当数据大于1024字节时,会自动在请求头加入Expect:100-continue,导致请求挂起,得不到目的服务器的响应.

解决方法:在发送请求前,在请求头部 手动设置Expect:为空 取消Expect:100-continue 以下是代码示例:

<?php
/**
 * PHP发送Json对象数据
 *
 * @param $url 请求url
 * @param $jsonStr 发送的json字符串
 * @return array
 */
function http_post_json($url, $jsonStr)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      ‘Content-Type: application/json; charset=utf-8‘,
      ‘Content-Length: ‘ . strlen($jsonStr),    ‘Expect:‘
    )
  );
  $response = curl_exec($ch);
  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  return array($httpCode, $response);
}

$arr = array(
        ‘service‘ => ‘s_scenic_info‘,
        ‘count‘ => 10 ,
        ‘batchNo‘ => ‘JQ201609011230590001‘,
        ‘flag‘ => ‘11111‘,
        ‘data‘ => array(
            array(
                ‘displayName‘ => ‘15980851200‘,
                ‘authenTicket‘ => ‘8b11d343d766d4af88d6b8746ec4e786‘,
                ‘authenUserId‘ => ‘1120d8d6ea4a4850b65d0faa40d6dffb‘,
                ‘timestamp‘ => ‘20151009195525‘
            ),
            array(
                ‘displayName‘ => ‘15980851200‘,
                ‘authenTicket‘ => ‘8b11d343d766d4af88d6b8746ec4e786‘,
                ‘authenUserId‘ =>‘1120d8d6ea4a4850b65d0faa40d6dffb‘,
                ‘timestamp‘ => ‘20151009195525‘
            )
        )
    );

$url = "http://wangming.hk1.ngrok.cc/tmdata/Dispatcher.do";
$jsonStr = json_encode($arr);
echo($jsonStr);
list($returnCode, $returnContent) = http_post_json($url, $jsonStr);
echo($returnContent)
?>

Expect:100-continue

当使用libcurl的POST方式时,如果POST数据的大小大于1024个字节,libcurl不会直接发送POST请求,而是会分为两步执行请求:

1、发送一个请求,该请求头部包含一个Expect: 100-continue的字段,用来询问server是否愿意接受数据

2、当接收到从server返回的100-continue的应答后,它才会真正的发起POST请求,将数据发送给server。

对于“100-continue"这个字段,RFC文档(http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3)是这么解释的:它可以让客户端在发送请求数据之前去判断服务器是否愿意接收该数据,如果服务器愿意接收,客户端才会真正发送数据,这么做的原因是如果客户端直接发送请求数据,但是服务器又将该请求拒绝的话,这种行为将带来很大的资源开销。所以为了避免这种情况,libcurl在发送大于1024字节的POST请求时采用了这种方法,但是相对的,它会引起请求延迟的加大,另外并不是所有的server都会正确处理并且应答”100-continue“,比如lighttpd,就会返回417”Expectation Failed“,造成请求逻辑出错。

如果确定服务器不会拒绝1024个字节以上的POST请求,就可以不使用该方法而且也可以避免以上提到的两个副作用

参考:

http://www.laruence.com/2011/01/20/1840.html

时间: 2024-10-10 17:20:20

HTTP POST 发送JSON格式数据(解决Expect:100-continue 问题)的相关文章

ajax发送json格式数据

前后端在做数据交互的时候 一定一定要表明你所发的的数据到底是什么格式 前段后交互 你不能骗人家,不然后端开发人员来找你的时候会抄着一根凳子腿. 你的数据时什么格式 你就应该准确无误告诉别人是什么格式 那么怎么告诉后端你要发送的数据的格式是什么呢 form 表单是通过 他的 enctype 而 ajax 是通过 contentType,如果你要传送的数据是json(通常只有json格式) 你需要这么写 contentType:'application/json' 要怎样发送一个json格式的数据呢

curl发送json格式数据

php的curl方法详细的见官方手册. curl_setopt用法:  http://www.php.net/manual/en/function.curl-setopt.php <?php $params = array( 'par1' => 'a', 'par2' => 11, ); $header = array("Content-type: application/json");// 注意header头,格式k:v $arrParams = json_enco

如何使用python内置的request发送JSON格式的数据

使用步骤如下: 一.如果想发送json格式的数据,需要使用request模块中的Request类来创建对象,作为urlopen函数的参数 二.header中添加content-type为application/json 三.使用json中dumps方法将请求体内容解析为字符串类型 from urllib import request import json # 请求体数据 request_data ={ "account": "xxxxxx", "sign

解析JSON格式数据

 别想一下造出大海,必须先由小河川开始. 本讲内容:解析JSON格式数据 1)比起XML,JSON的主要优势在于它的体积更小,在网络上传输的时候可以更省流量.但缺点在于,它的语义性较差,看起来不如XML直观. 2)解析JSON格式的数据有多种方式,常用的两种是:使用官方提供的JSONObject和谷歌的开源库GSON. 示例一:解析服务器返回的数据 一.JSONObject解析方式 步骤: 1.在服务器中定义一个JSONArray,并将服务器返回的数据传入到JSONArray对象中 2.循环

Spring MVC 前后台传递json格式数据 Content type &#39;application/x-www-form-urlencoded;charset=UTF-8&#39; not supported

报错如下: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported 解决方案: 引入如下包: 问题既解决. Spring MVC 前后台传递json格式数据 Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

ajax请求后台,返回json格式数据,模板!

添加一个用户的时候,需要找出公司下所有的部门,和相应部门下的角色,利用ajax请求,实现联动技术.将返回的json格式数据,添加到select标签下. <script type="text/javascript">        //加载出部门的信息            function loadGroup(){                            $.ajax({                    type:"post",  

使用getJSON()方法异步加载JSON格式数据

使用getJSON()方法异步加载JSON格式数据 使用getJSON()方法可以通过Ajax异步请求的方式,获取服务器中的数组,并对获取的数据进行解析,显示在页面中,它的调用格式为: jQuery.getJSON(url,[data],[callback])或$.getJSON(url,[data],[callback]) 其中,url参数为请求加载json格式文件的服务器地址,可选项data参数为请求时发送的数据,callback参数为数据请求成功后,执行的回调函数. 1 <!DOCTYPE

jQuery获取JSON格式数据方法

getJSON方法: jQuery.getJSON(url,data,success(data,status,xhr)) $("button").click(function(){ $.getJSON("demo_ajax_json.js",function(result_data){ $.each(result_data, function(index, name_value){ $("div").append(name_value + &qu

ios网络学习------6 json格式数据的请求处理

#import "MainViewController.h" #import "Video.h" #define kBaseURL @"http://192.168.3.252/~apple" @interface MainViewController ()<UITableViewDataSource, UITableViewDelegate> @property (strong, nonatomic) NSArray *dataLi