1.HTTP原理
(1)协议
1.协议概念:制定客户端与服务器之间的通讯规则。不同的协议的作用也不同。2.http协议:
- HTTP(HyperText Transfer Protocol) 超文本传输协议。
- 协议双方: 浏览器与web服务器
- 请求由浏览器发起的
- HTTP 协议中明确规定了请求数据和响应数据的格式(报文)
- 浏览器 请求 资源 要遵守 http 协议:
请求报文(请求行,请求头,请求体) - 服务器 返回 资源 要遵守 http 协议:
响应报文(响应行,响应头,响应体)
(2)端口
-
1.一个IP地址的端口可以有65536个,范围是从[0,65535])。不同的端口被不同的软件占用,以提供不同的服务。
- ip地址: 找到你的电脑 ( 一台电脑只有一个ip )
- 端口号: 找到电脑上具体的软件 ( 一台电脑可以有很多个端口号 )
-
2.一台电脑可以通过安装多个服务器端软件来提供服务,比如Web服务、FTP服务、SMTP服务等。显然,仅仅通过ip地址是无法区分不同的服务的,
这里就需要用到 “IP地址+端口号”来区分不同的服务。 -
3.通俗的来讲:
- 一台电脑只有一根网线,只会有一个ip. 所有的网络传输都是通过这根网线传输的, 但是电脑上有很多软件,你的操作系统是怎么知道这个网络请求是发给哪一个软件的。所以每一个软件都会有一个端口号。
- 端口: 一个软件服务对应一个端口
- 通过
netstat -a -n -o查看端口使用情况
(3)Content-Type
-
1.content-type作用
- 在http协议中,content-type用来告诉对方本次传输的数据的类型是什么。
-
2.请求头中的content-type
- 在请求头中设置content-type来告诉服务器,本次请求携带的数据是什么类型的
-
3.响应头中的content-type
- 在响应头中设置content-type来告诉服务器,本次返回的数据是什么类型的
-
4.常见的conteng-type
- .html:
res.setHeader('content-type', 'text/html;charset=utf8') - .css:
res.setHeader('content-type', 'text/css;charset=utf8') - .js:
res.setHeader('content-type', 'application/javascript') - .png:
res.setHeader('content-type', 'image/png') - json数据:
res.setHeader('content-type', 'application/json;charset=utf-8')
- .html:
(4)statuCode
①statuCode作用: 响应状态码
开发中,关于接口文档的状态码,一般有两种处理方式(都可以,前提是保持风格一致。 类似于js中的分号,要么都加,要么都不加)
方式一: 状态码放在响应行里面 res.sendStatus(400)
- 前端影响: 如果是2xx,则会执行axios的then方法。 如果是4xx,则会执行axios的catch方法。并且浏览器还会爆红。
方式二:状态码放在响应体中, 这种方式前端axios只会then方法。 前端需要自行判断状态码来写业务逻辑。
②常见状态码
- 2xx(绿色) :
请求成功 -
200 请求成功 -
204 : post请求体持续传输 - 3xx(黄色) :
重定向(服务器修改浏览器地址) -
302 : 重定向,服务器主动修改浏览器地址 - 4xx(红色) :
前端问题 -
400:参数错误 -
401:未身份验证(没登录) -
403:服务器拒绝访问(没有权限) -
404:路径错误 -
405:请求方法错误 -
413 : 文件太大 - 5xx(红色) :
服务器问题 -
500 : 服务器出问题 -
503 : 服务器`维护`或`超载`
(5)RESTful接口
1.后台接口需要有一个统一的规范
- 网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备…)。因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致API构架的流行,甚至出现"APIFirst"的设计思想。RESTful API是目前比较成熟的一套互联网应用程序的API设计理论。 以前的规范: 只有get和post
res.send('获取')
})
app.post('/addarticle',(req,res)=>{
res.send('添加')
})
app.post('/delarticle',(req,res)=>{
res.send('删除')
})
app.post('/updatearticle',(req,res)=>{
res.send('编辑')
})
2.REST(Representational State Transfer): 指定增删改查规范
- 表述性状态转换,REST指的是一组架构约束条件和原则。 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。REST本身并没有创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力, 更好地使用现有Web标准中的一些准则和约束。
类型:get
功能:获取文章信息
接口名:localhost:8080/articles
类型:post
功能:添加新文章
接口名:localhost:8080/articles
类型:delete
功能:删除文章
接口名:localhost:8080/articles
类型:put/patch
功能:编辑文章
RESTful设计是:
● 通过URL设计资源。接口名一般都是名词,不包含动词。
● 请求方式(get,post,delete,put)决定资源的操作类型
(6)nodejs实现服务端重定向
- 服务端重定向常见于某些网站引导登陆注册的功能(当我们访问网站首页的时候,会跳转到登陆注册的界面,例:某东)
- 服务端的重定向功能主要由响应头的302状态码来实现 nodejs原生重定向和express重定向实现方式,原理相同,但是代码略有区别(两者只能二选一,不能混用)
//(1)原生写法
// //设置响应状态码+响应头
// res.writeHead(302,{
// 'location':'http://127.0.0.1:3000'
// })
// //结束响应
// res.end()
//(2)express写法
res.setHeader('location','http://127.0.0.1:3000')//响应头
res.status(302).send()//设置302重定向 然后 结束响应
const http = require('http');
const fs = require('fs');
const path = require('path');
//2.创建服务器
let server = http.createServer((req,res)=>{
console.log(req.url);
//请求路径
let urlPath = req.url;
//请求方法
let method = req.method;
if(req.url === '/'){
//302表示重定向
//(1)设置重定向地址
res.writeHead(302, {
'Location': 'login' //键值对,键表示客户端浏览器将进行重定向 值:表示客户端浏览器重定向的请求
//add other headers here...
});
//(2)响应本次请求
res.end();
}
//登陆页
if(req.url === '/login'){
fs.readFile(path.join(__dirname,'login.html'),function(err,data){
if(err){
throw err;
}
res.end(data);
});
};
});
//3.开启服务器
server.listen(3000, ()=> {
console.log('服务器启动成功');
});
2.跨域问题介绍
(1)什么是跨域?
浏览器使用 ajax时,如果请求了的接口地址和 当前打开的页面地址 不同源 称之为跨域
- (1)ajax : 浏览器只有使用ajax发送请求才会出现跨域。 href属性与src属性不会出现跨域
- (2) 接口地址 : ajax请求的url
- (3)打开的页面:当前页面的window.location.href
- (4)不同源 : 浏览器使用ajax,向不同源的接口发送请求,称之为 跨域访问
(2)什么是同源?
同源定义 : 两个url地址的 协议 与 主机 与 端口 均一致 (&&)
- 协议:http , https , file
- 主机 : 域名或者ip地址 (127.0.0.1)
- 端口 :3000, 4399
不同源定义: 两个url地址,协议 主机 端口任何一个不一致 (||)
http:127.0.0.1:3000/abchttp:127.0.0.1:3000/efghttps:127.0.0.1:3000/efghttp:127.0.0.1:3000/hero/addhttp:127.0.0.1:4399/hero/addhttp:127.0.0.1:4399/hero/all
为什么要有同源与不同源?
- 出于安全考虑,浏览器不允许,页面向不同源的接口请求数据,因为如果 接口 和 网页不同源,浏览器认为是2个不同的 服务器,
- 不同的服务器中内容是不可控的,不允许访问了
跨域的几种解决方案
- 常用: CORS
- 面试官喜欢问:JSONP
- 浏览器主动设置允许跨域(需要用户主动设置,只对当前设置浏览器生效)
3.跨域解决方案一: CORS
-
CORS :全称
cross origin resource share(资源共享) -
工作原理: 服务器 在返回响应报文的时候,在响应头中 设置一个允许的header
res.setHeader('Access-Control-Allow-Origin', '*');
2-express使用中间件cors : 给所有的res添加默认请求头Access-Control-Allow-Origin
-
express有一个自带的中间件cors,它的作用是自动给每一个res设置默认请求头
- 这样就不用我们自己每一个接口都要设置一次了
cors中间件是最简单的中间,底层原理如下
res.setHeader('Access-Control-Allow-Origin', '*')//设置响应头
next()//执行下一个中间件
})
4.跨域解决方案二:原生jsonp
-
了解jsonp原理,首先一定要明白script标签的src属性做了什么事情-
(1)scr属性会给服务器发送请求, 请求一个js文件
-
(2)浏览器会解析执行这个js文件里面的代码
- 如果浏览器直接返回js代码,浏览器会立即执行
-
-
1.JSONP的核心原理:如果script标签的src属性的请求,服务器返回的是一个函数调用。则浏览器会执行这个函数
- 这是浏览器script标签的一个的漏洞(历史遗留问题)
2.实际开发中JSONP的工作流程
-
(1)设置script标签的src属性,向一个不同源的接口发送一个get请求
- JSONP只支持get请求,不支持post
-
(2)src属性发送请求时,在参数中额外携带一个callback的参数,参数值是一个在页面中预先定于好的函数名
-
callback : 这是发明jsonp技术的人提出的一个
君子之约,只要是jsonp前端程序员都统一将参数名定义为callback- PS:别的参数也行,只要和服务器协商好
-
callback属性值:预先定义的函数名,这个函数必须要在script标签之前定义
-
-
(3)服务器接收到请求之后,获取callback的参数值
-
(4)服务器将要响应的数据拼接成
函数调用格式,通过传参的方式将响应数据返回给浏览器
5.JSONP与CORS区别
-
CORS:
- 服务器返回响应头,前端无需任何处理
- 简单快捷,支持所有请求方式
-
JSONP
-
浏览器:自定义响应回调函数,使用script标签的src请求
- 利用浏览器的src属性没有跨域这一限制特点
-
服务器:接收callback参数,返回函数调用
-
处理复杂,并且只支持get请求
- 原因:get请求参数直接在url后面拼接,而post请求参数是放在请求体中
-
后记
如果发现内有语句或逻辑混乱的地方,还请各路大神指正。