趣谈http报文
http报文
请求报文
起始行
第一部分:显示method
method有很多种:get获得 post创建 put 更新 delete 删除 等
但是它这个定义只是一张纸上这么写的,我们完全可以按照我们自己的方法去实现这个web服务
比如说你想通过这个method把数据更新掉 完全没有问题 只不过你没有遵循http协议的语义化的定义去做
这样做的坏处是,如果有个不知情的人访问你的服务,他可能一不小心做了他他认为安全的操作,结果数据更新掉了。这就是语义存在的意义
第二部分
显示URL,一般只存放路由部分,因为你发送请求之前,tcp已经连接了,你已经知道你要去哪个主机,所以只需要告诉我你要访问哪个资源就行
第三部分
显示 协议版本 现在一般用http1.1 ,http2很快会普及
头部
描述我想要接收到的数据的格式
没有主体
响应报文
起始行:
第一部分:协议版本
第二部分:code ,代表这个请求现在是处于一个什么样的状态 200表示是正常的 OK的 我可以正常返回给你内容
200到300 300到400……都有它们的含义,含义是啥,就是后面那个英文的意思,这里是OK
典型的,比如401,表示你发送这个请求的时候没有认证,无法获取资源
但是在国内很多做web开发的同学,做服务器的时候,在他们眼里httpcode只有两种,200和500,不管数据请求是正确的,错的,还是没有认证,都会返回200,再返回一个数据,在这个数据里面,再去说明这个请求到底是正确还是错误。
这样的做法不够优秀,我们要遵从code语义,这样我们的服务更通用,更严谨
首部与主体
它们之间不止一条线,还有个空行
node创建本地服务器
创建一个本地服务器并启动
const http = require('http')http.createServer(function(request,response){
console.log('request come',request.url)
response.end('123')
}).listen(8800)
console.log('on')
启动成功
在gitbash里面,通过curl,我们可以获得一些信息,其实在浏览器里我们也能看,不过用这个工具更好
跨域其实是浏览器的规定
我们先来模拟一下跨域,感受一下
01.html
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var xhr =new XMLHttpRequest()
xhr.open('GET','http://127.0.0.1:8801/')
xhr.send()
</script>
</body>
</html>
02.js
const http = require('http')http.createServer(function(request,response){
console.log('request come',request.url)
response.end('123')
}).listen(8801)
console.log('on')
01.js
const http = require('http')const fs =require('fs')
http.createServer(function(request,response){
console.log('request come',request.url)
const html =fs.readFileSync('01.html','utf8')
//设置head
response.writeHead(200,{
'Content-Type':'text/html'
//Content-Type的作用,设置浏览器把文件解析为什么形式
})
response.end(html)
}).listen(8800)
console.log('01.js on')
启动01.js,报错,因为它没有设置服务端允许跨域的头
那我们要怎么设置才能使它可以跨域呢?
我们给02.js添加头部信息,返回头(其实相当于服务端设置允许你跨域访问我)
const http = require('http')http.createServer(function(request,response){
console.log('request come',request.url)
response.writeHead(200,{
'Access-Control-Allow-Origin':'*'
})
response.end('123')
}).listen(8801)
console.log('on')
再次起01服务,没有报错,且在network可以看到请求过来的信息
我们就通过一个步骤就让02服务接受跨域了,但是经过验证,我们发现,即使我们没有给02.js添加头部信息,返回头
启动02服务后,打印了request come/,所以其实这个请求已经发到了,
说明浏览器在发送这个请求的时候,它不知道我们这个服务是不是跨域的,所以它还是会发送请求,然后接收返回内容,只不过浏览器在接收到数据返回的时候,它发现没有头和设置允许('Access-Control-Allow-Origin':'*')
然后它就会把这个返回的数据忽略掉,然后再给你报个错
所以说请求是已经发送了,内容也已经返回了,只不过浏览器在解析这个内容的时候发现有误,所以它帮你拦截掉了!!这就是浏览器的功能
所以如果你在你自己的curl里发送,就没有跨域的概念,任何http请求都可以发送到,也可以返回内容并且输出
jsonp实现的原理
利用了浏览器对link img script等标签里面的url路径,加载内容时,是允许跨域的,浏览器不介意服务器有没有设置头
试一试,我们改一下两个文件
02.js
const http = require('http')http.createServer(function(request,response){
console.log('request come',request.url)
// response.writeHead(200,{
// 'Access-Control-Allow-Origin':'*'
// })
response.end('123')
}).listen(8801)
console.log('on')
01.html
<!-- <script>var xhr =new XMLHttpRequest()
xhr.open('GET','http://127.0.0.1:8801/')
xhr.send()
</script> -->
<script src="http://127.0.0.1:8801/"></script>
结果运行发现不报错,也请求成功了
就是在script标签里面去加载了一个链接,这个链接去访问服务器的某个请求,并且返回了内容。因为服务器返回的内容是可控的,所以在返回的内容里面的script标签里面写的可执行的js代码
在代码里面去调用jsonp,在发起请求之前,设置的一些内容
????好抽象
response.writeHead(200,{'Access-Control-Allow-Origin':'*'
})
跨域的头只有这样设置吗?
'*'代表谁都可以访问,所以这样是不安全的,那我们可以怎么改呢?
response.writeHead(200,{'Access-Control-Allow-Origin':'http://127.0.0.1:8800'
})
这样就可以啦,这样就只有http://127.0.0.1:8800/可以访问它
以上是 趣谈http报文 的全部内容, 来源链接: utcz.com/a/21933.html