3种方式构造HTTP请求详解(HTTP4)
构造HTTP请求方式
我们通过对HTTP
请求协议报头格式的学习知道了,我们可以通过3种基本方式去构造HTTP
请求!
而请求是在客户端构造的也就是属于前端的工作!
所以这3种构造请求的方式,大部分是通过前端代码来实现的,不过我们也可以通过java
代码基于socket
来实现!
基于
HTML/JS
实现构造!
- 基于
form
表单 - 基于
ajax
基于
java
代码实现构造!
- 基于
socket
form表单
HTML中的form
表单就可以构造HTTP
请求!
我们通过下面代码进行学习!
<!--form表单的形式构造http请求-->
<form action="https://www.csdn.net/" method="get"> <!--action 存放需要请求要提交的服务器url,method请求提交的的方法! -->
<input type="text" name="name"> <!--这里通过input标签实现-->
<input type="password" name="password"> <!--这里的name是一个特殊的属性,这是的name保存了键值对中的key,专门用于http构造请求的!-->
<input type="submit"> <!--提交按钮-->
</form>
表单标签- <
form
></form
>
这个标签允许用户输入一些信息提交到服务器中!
其中里面可以存放用户交互的组件
描述了要把数据按照什么方式, 提交到哪个页面中.
所以我们通过form
表单标签就可以编写一个http
请求!
<form action="https://www.csdn.net/" method="get">
这里通过键值对的形式 keyaction
保存的值是我们需要请求服务器的url
method
保存我们通过那种方法进行请求
这里的方法只能是post
和get
我们知道post
请求中要传输的数据保存在body
中
get
方法请求要传输的数据保证在url
中的querystring
查询字符串中!
这里我们通过get
方法进行构造,也就是说等下会通过querystring
等方式给服务器传输数据!
inpt
标签
我们知道form
标签中的组件就可以用于客户端和服务器进行交互!
我们通过input
标签!
type
属性,这个属性的取值代表这个input
具有不同含义!
type=text
这是一个普通文本框!
type=password
这是一个用于提交密码的文本框(输入内容不可见)
type=submit
提交表单按钮,我们最终要将我们构造的http
请求提交到服务器上!
<input type="text" name="name">
<input type="password" name="password">
这里的name
属性保存的就是querystring
查询字符串中键值对中的key
!
我们在输入框中输入的数据就对应了该name
属性下的value
值我们提交后就会在查询字符串中保存!
我们向服务器提交表单后,就构造了一个get
方法的http
请求!
我们发现我们已经跳转到了CSDN
的网站上!
因为我们提交的服务器url
就是C
站的首页!
我们通过fiddler
抓包,看我们构造的请求和服务器给我们返回的响应是怎样的!
请求
GET https://www.csdn.net/?name=bug%E9%83%AD&password=666666 HTTP/1.1
Host: www.csdn.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: uuid_tt_dd=10_30601611580-1653459529558-297725; log_Id_pv=846; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1655356530,1655382747,1655518119,1655547417;
式"],"reserveAddress":null,"job":"","strategy":"user_follow","tace_code":null,"user_days":"码龄5年","desc":"本文主要讲述
可以看到这里的响应明明返回的是200 ok
但是并没有给我处理这个请求!
基于ajax
ajax
是js
提供给我们的一种构造http
请求的方式!
传统的js
下的ajax
方式构造方式比较繁琐!
我们就通过引入jQuery
(js下的框架类似于java中spring框架)实现对ajax
方式请求的构造!
- 引入
jQuery
!
jQuery cdn链接
随便找个版本复制下来,这里有两种方式!
1).直接复制到HTML
代码中!
2).打开这个链接,然后复制下来,再创建一个js
本地文件,然后在HTML
中引入这个链接!
<!--方式一:复制到本地-->
<script src="jQuery.js"></script>
<!--方式二:直接复制-->
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
- 构造请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ajax方式构造请求</title>
</head>
<body>
<!--复制到本地-->
<!-- <script src="jQuery.js"></script> -->
<!--直接复制-->
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
script
<script>
$.ajax({
type: "get",
url:"https://www.csdn.net/",
success:function(body){
console.log("ajax方式构造请求,成功!"+body);
},
error:function(){
console.log("请求失败");
}
});
</script>
</body>
</html>
$
符号在js
中可以用于变量名!
在jQuery
中的很对函数都是通过这个$
对象访问!
$.ajax();
函数
这里的
ajax
函数需要传入参数是一个对象!
<script>
$.ajax({
type: "get",
url:"https://www.csdn.net/",
success:function(body){
console.log("ajax方式构造请求,成功!"+body);
},
error:function(){
console.log("请求失败");
}
});
</script>
这里的对象的数据也是用键值对的方式保存信息!
type:"post"
采用那种方法构造请求
这里的构造请求的方法不像form
表单只能选择post/get
这里所有构造请求的方法都可以选择!~
url:"https://www.csdn.next/"
请求访问的服务器url
域名!
success:function(body){ console.log("ajax方式构造请求,成功!"+body); }
请求成功,这里采用回调函数的方式,服务器的响应结果信息保存在body
中!
所以我们查看body
的信息就可以获取到从服务器中收到的消息!
error:function(){ console.log("请求失败"); }
请求失败,这里打印失败结果!
通过上方这些键值对就通过ajax
构造好了一个http
请求!
我们看一下我们这个请求最终响应结果!
请求失败了,虽然返回的状态码是200 ok
这里存在跨域访问!
我们看到这里报错了!
因为这里我们属于跨站访问了!
什么是跨站访问呢?
我们这里构造请求的
html
文件并不在该服务器下!
如果我们的请求网页就在https://www.csdn.net/
域名下的服务器,那么就不是跨站(跨域)访问
以后我们把请求写在自己的服务器下就不存在这个问题!
请求:
响应
基于java的方式
这里基于java
的方式构造http
请求比较繁琐,我们更少使用到!
我们一般通过java
中的TCPsocket
接口,按照请求报文的格式,构造出一个报文匹配的字符串,然后传入socket
发给服务器即可!
但是在实际开发中我们也不会直接就使用socket
构造,我们会向ajax
一样借助第三方库!
public class HttpClient {
private Socket socket;
private String ip;
private int port;
public HttpClient(String ip, int port) throws IOException {
this.ip = ip;
this.port = port;
socket = new Socket(ip, port);
}
public String get(String url) throws IOException {
StringBuilder request = new StringBuilder();
// 构造首行
request.append("GET " + url + " HTTP/1.1\n");
// 构造 header
request.append("Host: " + ip + ":" + port + "\n");
// 构造 空行
request.append("\n");
// 发送数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write(request.toString().getBytes());
// 读取响应数据
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024 * 1024];
int n = inputStream.read(buffer);
return new String(buffer, 0, n, "utf-8");
}
public String post(String url, String body) throws IOException {
StringBuilder request = new StringBuilder();
// 构造首行
request.append("POST " + url + " HTTP/1.1\n");
// 构造 header
request.append("Host: " + ip + ":" + port + "\n");
request.append("Content-Length: " + body.getBytes().length + "\n");
request.append("Content-Type: text/plain\n");
// 构造 空行
request.append("\n");
// 构造 body
request.append(body);
// 发送数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write(request.toString().getBytes());
// 读取响应数据
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024 * 1024];
int n = inputStream.read(buffer);
return new String(buffer, 0, n, "utf-8");
}
public static void main(String[] args) throws IOException {
HttpClient httpClient = new HttpClient("42.192.83.143", 8080);
String getResp = httpClient.get("/AjaxMockServer/info");
System.out.println(getResp);
String postResp = httpClient.post("/AjaxMockServer/info", "this is
body");
System.out.println(postResp);
}
}
可以看到比较繁琐,可以自行参考!
使用Java
构造的HTTP
客户端不再有 “跨域” 限制了, 此时也可以用来获取其他服务器的数据了.
跨域只是浏览器的行为, 对于ajax
有效. 对于其他语言来说一般都和跨域无关!
- 点赞
- 收藏
- 关注作者
评论(0)