趣谈http报文

http报文

Alt

请求报文

起始行

第一部分:显示method

method有很多种:get获得 post创建 put 更新 delete 删除 等

但是它这个定义只是一张纸上这么写的,我们完全可以按照我们自己的方法去实现这个web服务

比如说你想通过这个method把数据更新掉 完全没有问题 只不过你没有遵循http协议的语义化的定义去做

这样做的坏处是,如果有个不知情的人访问你的服务,他可能一不小心做了他他认为安全的操作,结果数据更新掉了。这就是语义存在的意义

第二部分

显示URL,一般只存放路由部分,因为你发送请求之前,tcp已经连接了,你已经知道你要去哪个主机,所以只需要告诉我你要访问哪个资源就行

第三部分

显示 协议版本 现在一般用http1.1 ,http2很快会普及

头部

描述我想要接收到的数据的格式

没有主体

响应报文

起始行:

第一部分:协议版本

第二部分:code ,代表这个请求现在是处于一个什么样的状态 200表示是正常的 OK的 我可以正常返回给你内容

Alt

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

回到顶部