学习路径:js基础语法+node.js内置api模块(fs、path、http等)+第三方api模块(express、mysql等)
常用node指令
在想要执行的代码的目录下打开cmd,然后输入node+要执行的js文件的路径
终端里的快捷键
1.fs文件系统模块
读取文件使用 fs.readFile() 方法,也可以使用同步的版本 fs.readFileSync()
fs.readFile(path[,options],callback)
const fs = require('fs') //导入fs
fs.readFile('/Users/joe/test.txt', 'utf8' , (err, data) => {
if (err) {
console.error(err)
return
}
console.log(data)
})
。。。。。。。。。。。。。。。。。。。。。。。
const fs = require('fs')
try {
const data = fs.readFileSync('/Users/joe/test.txt', 'utf8')
console.log(data)
} catch (err) {
console.error(err)
}
。。。。。。。。。。。。。。。。。。。。。。。。。。
可以通过指定标志来修改默认的行为:
fs.writeFile('/Users/joe/test.txt', content, { flag: 'a+' }, err => {})
fs.readFile() 和 fs.readFileSync() 都会在返回数据之前将文件的全部内容读取到内存中。
这意味着大文件会对内存的消耗和程序执行的速度产生重大的影响。
写入文件是使用 fs.writeFile() API,也可以使用同步的版本 fs.writeFileSync()
const fs = require('fs') //导入fs
const content = '一些内容'
fs.writeFile('/Users/joe/test.txt', content, err => {
if (err) {
console.error(err)
return
}
//文件写入成功。
})
。。。。。。。。。。。。。。。。。。。。。。。。。。。。
const fs = require('fs')
const content = '一些内容'
try {
const data = fs.writeFileSync('/Users/joe/test.txt', content)
//文件写入成功。
} catch (err) {
console.error(err)
}
可能会使用的标志有:
- r+ 打开文件用于读写。
- w+ 打开文件用于读写,将流定位到文件的开头。如果文件不存在则创建文件。
- a 打开文件用于写入,将流定位到文件的末尾。如果文件不存在则创建文件。
- a+ 打开文件用于读写,将流定位到文件的末尾。如果文件不存在则创建文件。
Node.js 的 fs 核心模块提供了许多便捷的方法用于处理文件夹。
使用 fs.access() 检查文件夹是否存在以及 Node.js 是否具有访问权限。
创建新的文件夹
使用 fs.mkdir() 或 fs.mkdirSync() 可以创建新的文件夹。
__dirname表示当前编写的文件所处的目录,用它来进行路径拼接就能保证移植性和维护性。
2.path路径模块
- path.basename()返回路径的最后一部分
- path.dirname()返回路径的目录部分
- path.extname()返回路径的扩展名部分。
- path.isAbsolute()如果是绝对路径,则返回 true。
- path.join()连接路径的两个或多个部分
- path.normalize()当包含类似 .、.. 或双斜杠等相对的说明符时,则尝试计算实际的路径
- path.parse()解析对象的路径为组成其的片段
- path.relative()接受 2 个路径作为参数。 基于当前工作目录,返回从第一个路径到第二个路径的相对路径。
- path.resolve()可以使用 path.resolve() 获得相对路径的绝对路径计算
3.http模块
//1.导入http模块
const http = require('http')
//2.创建web服务器实例
const server = http.createServer()
//3.为服务器实例绑定request事件,调用.on(),监听客户端的请求
server.on(request,(req,res)=>{
console.log('someone visit our web server')
})
//4.启动服务器
server.listen(8080,function(){
console.log('server running at http://127.0.0.1:8080')
})
const http = require('http')
const server = http.createServer()
server.on('request',(req, res)=>{
// 1.获取URL地址
const url = req.url
// 2.设置默认的响应内容为404 Not found
let content = "<h1>404 Not found!</h1>"
// 3.判断用户请求的是否为/或/index.html
// 4.判断用户请求的是否为/about.html
if(url === '/' || url ==='/index.html'){
content = '<h1>首页</h1>'
}else if(url === '/about.html'){
content = '<h1>关于页面</h1>'
}
// 5.设置Content-Type响应头,防止中文乱码
res.setHeader('Content-Type','text/html; charset=utf-8')
// 6.使用res.end()把内容响应给客户端
res.end(content)
})
server.listen(80,()=>{
console.log('server running at http://127.0.0.1');
})
4.模块化
加载模块
// 1.加载内置的fs模块
const fs = require('fs')
// 2.加载用户的自定义模块
const custom = require('./模块化.js')
// 3.加载第三方模块
const moment = require('moment')
注:使用require()方法加载其他模块时,会执行被加载模块中的代码。
模块作用域
每个.js自定义模块中都有一个module对象,它里面存储了和当前模块相关的信息
默认情况下,exports和module.exports指向同一个对象。最终的共享结果,还是以module.exports指向的对象为准。
1.require()模块时,得到的永远是module.exports指向对象
注意:为了防止混乱,建议不要在同一个模块中同时使用exports和module.exports。
//1
exports.username = 'zs'
//为module.exports又赋值了一个新的对象
module.exports = {
gender:'男',
age:22
}
最终结果是{gender:'男',age:22}
//2
module.exports.username = 'zs'
//为exports又赋值了一个新的对象
exports = {
gender:'男',
age:22
}
最终结果是{usename:'zs'}
//3
//两个都没有赋值新的对象,指向的是同一个对象
exports.username = 'zs'
module.exports.gender='男'
最终结果是{username:'zs',gender:'男'}
//4
exports = {
username : 'zs',
gender:'男',
}
module.exports = exports
module.exports.age = '22'
最终结果是{username:'zs',gender:'男',age:22}
2.module变量是一个对象,它的exports属性是对外的接口。
3.加载某个模块,其实是加载该模块的module.exports属性。require()方法用于加载模块
5.npm与包
node的内置模块仅提供了一些底层的API,导致在基于内置模块进行项目开发时,效率很低。
包是基于内置模块封装出来的,提供了更高级、更方便的API,极大的提高了开发效率。
function dateFormat(dtStr){
const dt = new Date(dtStr)
const y = dt.getFullYear()
const m = padZero(dt.getMonth()+1)
const d = padZero(dt.getDate())
const hh = padZero(dt.getHours())
const mm = padZero(dt.getMinutes())
const ss = padZero(dt.getSeconds())
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
// 定义补零的函数
function padZero(n){
return n > 9 ? n : '0' + n
}
module.exports = {
dateFormat
}
// 导入自定义的格式化时间的模块
const TIME = require('./dateFormat')
// 调用方法,进行时间的格式化
const dt = new Date()
// console.log(dt);
const newDT = TIME.dateFormat(dt)
console.log(newDT);
1.使用npm包管理工具,在项目中安装格式化时间的包moment
// 导入需要的包
// 注意:导入的名称就是装包时候的名称
const moment = require('moment')
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
console.log(dt);
命令:npm init -y
可以在执行命令所处的目录中,快速新建package.json文件。这个命令只能在英文的目录下成功运行,所以项目文件夹的名称不要使用中文,不能出现空格。
package.json中必须包含name(包的名字),version(版本号),main(包的入口)。
可以运行npm uninstall命令(没有简写),来卸载指定的包。
如果某些包只在项目开发阶段会用到,在项目上线之后不会用到,则建议把这些包记录到devDependencies节点中。如果某些包在开发和项目上线之后都需要用到,则建议把这些包记录到dependencies节点中。
项目包:
npm i 包名 -D
#开发依赖包(会被记录到devDependencies节点中的包,只在开发期间会用到)
npm i 包名
#核心依赖包(被记录到dependencies节点中的包,只在开发期间和项目上线之后都会用到)
全局包:
在执行npm i 命令时,如果提供了-g参数,则会把包装安装为全局包。
注意:只有工具性质的包,才有全局安装的必要性。因为他们提供了好用的终端命令。
将下包的镜像源切换为taobao镜像:nrm use taobao
i5ting_toc是一个可以把md文档转为html页面的小工具。
使用:i5ting_toc -f 要转换的md文件路径 -o
,-o表示转换完成后自动在浏览器中打开。
开发属于自己的包
写包:
{
"name": "mytools-wq",
"version": "1.0.0",
"main": "index.js",
"description": "提供了格式化时间、HTMLEscape相关的功能",
"keywords": ["dateFormat","escape"],
"license": "ISC"
}
入口文件:
// 这是包的入口文件
const date = require('./src/dateFormat')
const escape = require('./src/htmlEscape')
// 向外暴露成员
module.exports = {
...date,
...escape
}
// 定义格式化时间的函数
function dateFormat(dateStr) {
const dt = new Date(dateStr)
const y = dt.getFullYear()
const m = padZero(dt.getMonth() + 1)
const d = padZero(dt.getDate())
const hh = padZero(dt.getHours())
const mm = padZero(dt.getMinutes())
const ss = padZero(dt.getSeconds())
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
// 定义补零的函数
function padZero(n) {
return n > 9 ? n : '0' + n
}
// 向外暴露成员
module.exports = {
dateFormat
}
// 定义转义HTML字符的函数
function htmlEscape(htmlStr) {
return htmlStr.replace(/<|>|"|&/g, (match) => {
switch (match) {
case '<':
return '&lt;'
case '>':
return '&gt;'
case '"':
return '&quot;'
case '&':
return '&amp;'
}
})
}
// 定义还原HTML字符串的函数
function htmlUnEscape(htmlStr){
return htmlStr.replace(/&lt;|&gt;|&quot;|&amp;/g,(match)=>{
switch(match){
case '&lt;':
return "<"
case '&gt;':
return '>'
case '&quot;':
return '"'
case '&amp;':
return '&'
}
})
}
// 向外暴露成员
module.exports = {
htmlEscape,
htmlUnEscape
}
README.md文件中应包含:安装方式、导入方式、格式化时间、转义HTML中的特殊字符、还原HTML中的特殊字符、开源协议。
发布包
先注册一个npm账号然后终端登录,然后将下载包的路径由淘宝镜像改为原来的npm,然后将终端切换到包的根目录,
运行npm unpublish 包名 --force
命令,即可从npm删除已发布的包。
注意:
1.这个命令只能删除72小时内发布的包
3.发包要慎重,尽量不发无意义的包
模块的加载机制
模块在第一次加载后会被缓存。这意味着多次调用require()不会导致模块代码被执行多次,它们会优先从缓存中加载,从而提高模块的加载效率。
内置模块的加载优先级最高。
加载自定义模块必须指定以./或../开头的路径标识符。如果没有路径标识符,那么node就会将它当做内置模块或第三方模块进行加载。
express
express的基本使用
app.get('请求URL',function(req,res){ /*处理函数*/})
app.post('请求URL',function(req,res){ /*处理函数*/})
res.send()方法,可以把处理好的内容,发送给客户端(把内容响应给客户端)
// Get 请求
app.get('/', (req, res) => {
res.send('欢迎使用 Express(GET)');
});
// POST 请求
app.post('/', (req, res) => {
res.send('欢迎使用 Express(POST)');
});
// Put 请求
app.put('/', (req, res) => {
res.send('欢迎使用 Express(PUT)');
});
app.delete('/', (req, res) => {
res.send('欢迎使用 Express(DELETE)');
});
// ... 等等其他请求方式
// 路径支持正则表达式
app.get('/a+b', (req, res) => {
res.send('类似于 /ab、/aab、/aaab 等的路径均可访问');
})
// 1.导入express
const express = require("express")
// 2.创建web服务器
const app = express()
// 4.监听客户端的GET和POST请求,并向客户端响应具体的内容
app.get('/user',(req,res)=>{
// 调用express提供的res.send()方法,向客户端响应一个JSON对象
res.send({name:'zs',age:20,gender:'男'})
})
app.post('/user',(req,res)=>{
// 调用express提供的res.send()方法,向客户端响应一个文本字符串
res.send("请求成功")
})
app.get('/',(req,res)=>{
// 通过req.query可以获取到客户端发送过来的查询参数
// 注意:默认情况下,req.query是一个空对象
console.log(req.query);
res.send(req.query)
})
app.get('/user/:id',(req,res)=>{
// req.params是动态匹配到的URL参数,默认也是一个空对象。
console.log(req.params);
res.send(req.params)
})
// 3.启动web服务器,调用app.listen(端口号,启动成功后的回调函数)
app.listen(80,()=>{
console.log("express server running at http://127.0.0.1");
})
获取URL中携带的查询参数
app.get('/',(req,res)=>{
// 通过req.query可以获取到客户端发送过来的查询参数
// 注意:默认情况下,req.query是一个空对象
console.log(req.query);
res.send(req.query)
})
req.query对象,可以访问到客户端通过查询字符串的形式,发送到服务器的参数。
获取URL中的动态参数
req.params对象,可以访问到URL中,通过 : 匹配的动态参数:
//id可以为其他的名称,但是:一定不可省,可以有多个动态参数
app.get('/user/:id',(req,res)=>{
// req.params是动态匹配到的URL参数,默认也是一个空对象。
console.log(req.params);
res.send(req.params)
})
const express = require('express')
const app = express()
// 在这里,调用express.static()方法,快速的对外提供静态资源
app.use(express.static('想要打开的文件目录'))
app.listen(80,()=>{
console.log("express server running at http://127.0.0.1");
})
访问静态资源文件时,express.static()函数会根据目录的添加顺序查找所需文件。
如果希望在托管的静态资源访问路径之前,挂载路径前缀,则可使用以下方式:
nodemon用来监视node.js应用程序中的任何更改并自动重启服务,非常适合用在开发环境中。
nodemon将监视启动目录中的文件,如果有任何文件更改,nodemon将自动重新启动node应用程序。
使用教程
3、启动应用
4、使用帮助
7. 帮助命令
1.以管理员身份运行powershell 2.输入set-ExecutionPolicy RemoteSigned 3.选择Y或者A
express路由
在express中,路由指的是客户端请求与服务器处理函数之间的映射关系。
express中的路由分3部分组成,分别是请求的类型、请求的URL地址、处理函数,
格式:app.MATHOD(PATH,HANDLER)
MATHOD——请求类型,PATH——请求的URL地址,HANDLER——处理函数
每当一个请求到达服务器之后,需要先经过路由的匹配,只要匹配成功,才会调用相应的处理函数。
在匹配时,会按照路由的顺序进行匹配,如果请求类型和请求的URL同时匹配成功,则express会将这次请求,转交给对应的function函数进行处理。
路由匹配的注意点:
1.按照定义的先后顺序进行匹配
2.请求类型和请求的URL同时匹配成功,才会调用对应的处理函数
路由的使用
const express = require('express')
const app = express()
// 挂载路由
app.get('/',(req,res)=>{
res.send('hello world')
})
app.post('/',(req,res)=>{
res.send('Post Request.')
})
app.listen(80,()=>{
console.log('http://127.0.0.1');
})
2.模块化路由
步骤:
1.创建路由模块对应的.js文件
2.调用express.Router()函数创建路由对象
3.向路由对象上挂载具体的路由
5.使用app.use()函数注册路由模块
// 这是路由模块
// 1.导入express
const express = require('express')
// 2.调用express.Router()函数创建路由对象
const router = express.Router()
// 3.向路由对象上挂载具体的路由
router.get('/',(req,res)=>{
res.send('Get user list')
})
// 4.使用module.exports向外共享路由对象
module.exports = router
const express = require('express')
const app = express()
// 1.导入路由模块
const router = require('./router.js')
// 2.使用app.use()函数注册路由模块
app.use(router)
//注意app.use()函数的作用,就是来注册全局中间件
app.listen(80,()=>{
console.log('http://127.0.0.1');
})
express中间件
express中间件的调用流程:当一个请求到达express的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
express的中间件,本质就是一个function处理函数。
中间件函数的形参列表中,必须包含next参数。而路由处理函数中只包含req和res。
var app = express();
// 没有挂载路径的中间件,应用的每个请求都会执行该中间件
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 挂载至 /user/:id 的中间件,任何指向 /user/:id 的请求都会执行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 路由和句柄函数(中间件系统),处理指向 /user/:id 的 GET 请求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。
const mw = function(req,res,next){
console.log('这是最简单的中间件函数')
//2把流转关系,转交给下一个中间件或路由
next()
}
全局生效的中间件
通过调用app.use(中间件函数),即可定义一个全局生效的中间件
app.use(function(req,res,next){
console.log('这是一个最简单的中间件函数')
next()
})
中间件的作用
多个中间件之间,共享一份req和res。基于这样的特性,我们可以在上游的中间件中,统一为req和res对象添加自定义的属性和方法,供下游的中间件或路由使用。
app.use(function (req, res, next) {
// 获取到请求到达服务器的时间
const time = Date.now()
// 为req对象,挂载自定义属性,从而把时间共享给后面的所有路由
req.startTime = time
next()
})
app.get('/', (req, res) => {
res.send('Home page.' + req.startTime)
})
app.post('/', (req, res) => {
res.send('User page.' + req.startTime)
})
定义多个全局中间件:连续多次使用app.use()定义多个中间件就行了,客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行调用。
局部生效的中间件
不使用app.use()定义的中间件叫做局部生效的中间件
const mw = (req, res, next) => {
console.log('调用了局部生效的中间件')
next()
}
app.get('/', mw, (req, res) => {
res.send('Home page.')
})
app.get('/user', (req, res) => {
res.send('User page.')
})
了解中间件的5个注意事项
1.一定要路由之前注册中间件
2.客户端发送过来的请求,可以连续调用多个中间件进行处理
3.执行完中间件的业务代码之后,不要忘记调用next()函数
4.next函数后面不要再写额外的代码
5.连续调用多个中间件时,多个中间件之间,共享req和res对象
中间件的分类
1.应用级中间件
应用级中间件绑定到 app 对象 使用 app.use() 和 app.METHOD(),其中, METHOD 是需要处理的 HTTP 请求的方法,例如 GET, PUT, POST 等等,全部小写。
var app = express();
// 没有挂载路径的中间件,应用的每个请求都会执行该中间件
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 挂载至 /user/:id 的中间件,任何指向 /user/:id 的请求都会执行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 路由和句柄函数(中间件系统),处理指向 /user/:id 的 GET 请求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
2.路由级中间件
绑定到express.Router()实例上的中间件,叫做路由级别的中间件。
var app = express();
var router = express.Router();
// 没有挂载路径的中间件,通过该路由的每个请求都会执行该中间件
router.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 一个中间件栈,显示任何指向 /user/:id 的 HTTP 请求的信息
router.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}, function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 一个中间件栈,处理指向 /user/:id 的 GET 请求
router.get('/user/:id', function (req, res, next) {
// 如果 user id 为 0, 跳到下一个路由
if (req.params.id == 0) next('route');
// 负责将控制权交给栈中下一个中间件
else next(); //
}, function (req, res, next) {
// 渲染常规页面
res.render('regular');
});
// 处理 /user/:id, 渲染一个特殊页面
router.get('/user/:id', function (req, res, next) {
console.log(req.params.id);
res.render('special');
});
// 将路由挂载至应用
app.use('/', router);
3.错误处理中间件
错误处理中间件和其他中间件定义类似,只是要使用 4 个参数,而不是 3 个,其签名如下: (err, req, res, next)。顺序不能更换。必须注册在所有路由之后。
app.get('/', (req, res) => {
// 人为制造错误
throw new Error('服务器内部发生了错误!')
})
// 定义错误级别的中间件,捕获整个项目的异常错误,从而防止程序的崩溃
app.use((err,req,res,next)=>{
console.log('发生了错误'+err.message);
res.send('Error:' + err.message)
})
4.内置中间件
常用的内置中间件:
1.express.static——快速托管静态资源的内置中间件,例如:HTML文件、图片、css样式等(无兼容性)
app.use()
2.express.json——解析JSON格式的请求体数据(有兼容性,仅在4.16.0+版本中可用)
app.use(express.json)
3.express.urlencoded——解析 URL-encode格式的请求体数据(有兼容性,仅在4.16.0+版本中可用)
5.第三方中间件
在express@4.16.0之前的版本,经常使用body–parse这个第三方中间件,来解析请求体数据
npm install cookie-parser
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
// 加载用于解析 cookie 的中间件
app.use(cookieParser());
自定义中间件
顾名思义,就是自己定义的中间件。就是在回调函数中写入自己需要的方法事件。
1.定义中间件
3.监听req的end事件
5.将解析出来的数据对象挂载为req.body
6.将自定义中间件封装为模块
//post参数解析中间件
function bodyParser(req,res,next){
let arr = [];
req.on("data", chunk => {
arr.push(chunk);//将读取到的数据存储到数组中
});
req.on('end', () => { //post 数据读取完毕
let data = Buffer.concat(arr).toString();
// console.log(qs.parse(data));
req.body = qs.parse(data);//将读取到的post参数数据存储到request对象中body属性中
next();//注意,一定要数据读取完毕之后,在顺延(转发)
})
}
//自定义post参数解析中间件
app.use(bodyParser);
编写接口
//导入express
const express = require('express')
//创建服务器实例
const app = express()
//配置解析表单数据的中间件
app.use(express.urlencoded({extended:false}))
// 导入路由模块
const router = require('./apiRouter.js')
// 把路由模块注册到app上
app.use('/api',router)
//启动服务器
app.listen(80, () => {
console.log('http://127.0.0.1')
})
const express = require('express')
const router = express.Router()
// 在这里挂载对应的路由
// get请求
router.get('/get', (req, res) => {
// 通过req.query获取客户端通过查询字符串,发送到服务器的数据
const query = req.query
// 调用res.send()向客户端响应处理的结果
res.send({
status: 0, //0表示处理成功,1表示处理失败
msg: 'GET请求成功!', //状态的描述
data: query //需要响应给客户端的数据
})
})
//post请求
router.post('/post', (req, res) => {
// 1.获取客户端通过的请求体,发送到服务器的URL-encoded数据
// 如果要获取URL-encoded格式的请求体数据,必须配置中间件app.use(express.urlencoded({extended:false}))
const body = req.body
// 2.调用res.send()方法,把数据响应给客户端
res.send({
status: 0,
msg: 'post请求成功',
data: body
})
})
module.exports = router
CORS跨域资源共享
2.使用const cors = require("cors")
导入中间件
3.在路由之前调用app.use(cors())
配置中间件
什么是CORS
CORS (Cross-Origin Resource Sharing)(或通俗地译为跨域资源共享)是一种基于 HTTP响应 头的机制,
这些http响应头决定浏览器是否阻止前端js代码跨域获取资源。
该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的”预检“请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。
CORS的注意事项
1.CORS主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了CORS的接口。
2.CORS在浏览器中有兼容性,只有支持XMLHttpRequest Level2的浏览器,才能正常访问开启了CORS的服务端接口
CORS响应头
1.Origin:当前请求源,和响应头里的Access-Control-Allow-Origin 对标, 是否允许当前源访问,Origin是不可修改的
2.Access-Control-Request-Headers:本次真实请求的额外请求头,和响应头里的Access-Control-Allow-Headers对标,是否允许真实请求的请求头
3.Access-Control-Request-Method:本次真实请求的额外方法,和响应头里的Access-Control-Allow-Methods对标,是否允许真实请求使用的请求方法
app.all('/cors-server',(request,response) => {
//设置响应头
//以下都是允许所有的http请求方法
response.setHeader("Access-Control-Allow-Origin",'*');
response.setHeader("Access-Control-Allow-Headers",'*');
response.setHeader("Access-Control-Allow-Method",'*');
response.send('hello CORS');
})
cors的两种请求
请求方式为HEAD、POST 或者 GET
http头信息不超出一下字段:Accept、Accept-Language 、 Content-Language、 Last-Event-ID、 Content-Type(限于三个值:application/x-www–form–urlencoded、multipart/form–data、text/plain)
为什么要分为简单请求和非简单请求,因为浏览器对这两种请求方式的处理方式是不同的。
2、预检请求 :
非简单请求是那种对服务器有特殊要求的请求,请求方法不是HEAD、POST 或者 GET,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为“预检”请求(preflight)。
这两个,其实一个是另外一个的对立面。而且最大的不同在于,简单请求只发起一次网络请求。
而预检请求会发起两次,先发起一个option请求后,才会发起它真正的请求!
原文地址:https://blog.csdn.net/m0_52074342/article/details/125719364
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_43592.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!