java向服务器post请求时首部字段content-length的计算方法

当java向服务器post请求时,首部中有一个Content-length字段,即请求主体中的字节数。首部在主体的前面。不过,要写入首部,需要知道主体的长度,而在写首部的时候可能还不知道主体的长度。正常情况下,对于这个两难的问题。
如图所示
这里写图片描述
Java的解决办法是:对于从HttpURLConnection获取的OutputStream ,将写入此OutputStream的所有内容缓存,直到流关闭。此时它就会知道主体中有多少字节,所以有足够的信息来写入Content-length首部。

这种模式对于响应典型Web表单的短请求很合适。不过,对于非常长的表单或一些SOAP消息,响应时负担会很大。用HTTP PUT发送中等到大型文挡时会很浪费,也很慢。如果Java 通过网络发送第一字节之前,不需要等待写入最后一字节,将会高效得多。

Java 为这个问题提供了两种解决方案。

解决方案1:如果你知道数据的大小,例如使用HTTP PUT上传一个已知大小的文件,可以将数据的大小告诉HttpURLConnection对象。

解决方案2:如果预先不知道数据大小,可以使用分块传输编码方式。在分块传输编码方式中,请求主体以多个部分发送,每个部分都有自己单独的内容长度。要启用分块传输编码方式,只要在连接URL之前将分块大小传入setChunkedStreamingMode()方法(需要服务器支持分块传输编码方式,所以,,除非确实需要,否则不要使用分块传输编码方式)。

如果恰好预先知道请求数据的大小,可以将这个信息提供给HttpURLConnection对象,从而优化连接。如果这样做,Java会立即通过网络将数据以流方式发送。否则,它必须缓存你写入的所有数据来确定内容长度,而且只有在你关闭流之后才能通过网络发送数据。如果知道数据的具体大小,可以将这个数传递给setFixedlengthStreamingMode()方法。由于这个数可能实际大于int所能存储的最大整数(大约21亿个字节,大约200M),所以在Java 7及以后版本中可以使用一个long。

注意两个问题:

  1. Java会在HTTP首部的Content-length字段中使用这个数。不过,如果接下来试图写入的数据多于或少于给出的这个字节数, Java会抛出一个IOException异常。
  2. 流模式确实会妨碍身份认证和重定向。如果给定的URL要求认证或重定向,就会抛出一个HttpRetryException异常
### 回答1: 在JavaScript中获取`Content-Disposition`首部可以通过从HTTP响应头中获取该首部来实现。 以下是一种获取`Content-Disposition`首部的示例方法: ```javascript // 假设 response 是一个 XMLHttpRequest 对象或者 Fetch API 返回的 Response 对象 const contentDispositionHeader = response.headers.get('Content-Disposition'); if (contentDispositionHeader) { // contentDispositionHeader 的值可能是 "attachment; filename=example.txt" // 在这里你可以提取出文件名 example.txt,用于后续的操作 } ``` 在这个例子中,我们通过 `headers.get('Content-Disposition')` 方法来获取HTTP响应头中的`Content-Disposition`首部。如果该首部存在,我们可以对其进行解析以获取有用的信息。 请注意,获取HTTP响应头中的任何首部都需要注意跨域问题和CORS策略。如果HTTP响应不允许JavaScript从另一个域获取该首部,则此方法可能无法正常工作。 ### 回答2: 使用JavaScript获取Content-Disposition的步骤如下: 1. 发送HTTP请求:使用XMLHttpRequest或fetch等方法发送HTTP GET或POST请求获取文件的内容。 2. 获取HTTP响应头信息:获取响应头信息,包括Content-Disposition头部。 3. 解析Content-Disposition:使用正则表达式或字符串处理方法来从响应头中提取Content-Disposition的值。 4. 提取文件名:根据Content-Disposition的值,提取文件名部分。 5. 进一步处理:根据需要进行进一步的处理,例如对文件名进行编码转换或其他操作。 下面是一个基本的JavaScript函数示例,用于获取Content-Disposition的文件名部分: ```javascript function getFileNameFromContentDisposition(contentDisposition) { var match = contentDisposition.match(/filename\*?=([^;]+)/i); if (match && match[1]) { // 文件名包含在filename*或filename字段中 var fileName = match[1].trim(); // 检查是否包含编码信息 if (fileName.startsWith("UTF-8''")) { // 去除编码信息,并进行解码 fileName = decodeURIComponent(fileName.substring(7)); } return fileName; } else { // 直接从Content-Disposition中提取文件名 var startIndex = contentDisposition.indexOf("filename=") + 9; var endIndex = contentDisposition.length; var encodedFileName = contentDisposition.substring(startIndex, endIndex).trim(); var fileName = decodeURIComponent(encodedFileName); return fileName; } } // 示例用法 var contentDisposition = "attachment; filename*=UTF-8''%E6%B5%8B%E8%AF%95.txt"; var fileName = getFileNameFromContentDisposition(contentDisposition); console.log(fileName); // 输出:测试.txt ``` 在上述示例中,我们定义了一个名为getFileNameFromContentDisposition的函数,该函数接受Content-Disposition的值作为参数,并返回文件名部分。函数内部使用正则表达式和字符串处理方法来解析Content-Disposition,并从中提取文件名。如果文件名包含编码信息,则会进行相应的解码。最后,在示例用法中,我们传入一个Content-Disposition的示例值,然后打印解析得到的文件名。 ### 回答3: 在JavaScript中可以使用XMLHttpRequest对象来获取服务器的响应头信息,包括content-disposition。 首先,创建一个XMLHttpRequest对象: ```javascript var xhr = new XMLHttpRequest(); ``` 然后,使用open方法来指定请求的方法和URL: ```javascript xhr.open('GET', 'your_url_here', true); ``` 接下来,设置响应类型为arraybuffer或blob,以便能够获取到完整的响应内容: ```javascript xhr.responseType = 'arraybuffer'; // 或者 'blob' ``` 然后,发送请求: ```javascript xhr.send(); ``` 当请求完成,可以通过xhr的getResponseHeader方法来获取指定的响应头信息,例如content-disposition: ```javascript var contentDisposition = xhr.getResponseHeader('content-disposition'); ``` 注意:由于涉及到跨域请求,如果服务器端没有正确设置Access-Control-Allow-Origin头信息,浏览器会阻止获取到响应头信息。 另外,如果使用的是fetch API进行网络请求,可以使用第二个then回调函数获取响应对象,并通过响应对象的headers属性获取到相应的头信息: ```javascript fetch('your_url_here').then(function(response) { var contentDisposition = response.headers.get('content-disposition'); }); ``` 总结起来,通过创建XMLHttpRequest对象或使用fetch API,然后发送请求,最后通过相应的方法或属性来获取content-disposition信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值