在前面的HTTP模块内容内容当中讲到这个跨域的问题,跨域就涉及到浏览器的同源策略,跨域只出现在浏览器当中,在浏览器当中去执行脚本的时候会进行一个同源检测,只有是同源的脚本才会被浏览器执行,不同源就是跨域,同源就是请求的url协议、域名、端口号要相同,只有相同的才能够互相访问,不同就会出现跨域问题。下面用一个简单的例子图示理解:
下面来回顾之前通过后端处理的方式解决跨域的问题;通过后端的设置来解决请求跨域的问题:
Access to XMLHttpRequest at 'http://127.0.0.1:3000/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
http://127.0.0.1:5500发起请求http://127.0.0.1:3000/中的数据,协议相同,域名相同,端口号不同出现跨域请求的问题,通过后端的设置解决跨域的问题,在后端设置中设置以下属性:
Access-Control-Allow-Origin",'*'
Access-Control-Allow-Headers","X-Requested-With"
Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"
那么在HTTP模块中已经具体的讲述,就不在赘述了;
上一篇内容讲到这个中间件,那么这里来用使用cors中间件来解决跨域问题,cors是Express的一个第三方中间件;cors(cross-origin-resource Sharing)意思就是跨域资源共享,是由一系列的HTTP响应头组成,这些HTTP响应头也就决定了浏览器是否要阻止前端的js脚本去跨域请求获取资源,CROS主要是在服务器进行配置的,客户端浏览器无须做任何额外的配置,就可以开启了CROS的接口,但CORS在浏览器中有兼容性,例如IE10+,Chrome4+,FireFox3.5+;下面就来安装和使用这个cors中间件:
1. 安装cors第三方中间件;
npm install cors
2. 导入cors第三方中间件使用;
const express = require('express');
const app = express();
const fs = require('fs');
const cors = require('cors');
app.use(cors());
app.get('/',function(req,res){
let data = fs.readFileSync(__dirname + '/全国行政区数据.json')
res.end(data);
})
app.listen('3000',function(){
console.log('Server Running || 127.0.0.1:3000');
})
3. 测试使用;
通过编写一个index.html页面发起ajax请求:
全国行政区
全国行政区
如果不使用的话,将app.use(cors())内容人注视点然后打开浏览器来对比使用cors中间件后HTTP响应头(Response Hearders):
Access-Control-Allow-Orgin
Access-Control-Allow-Orgin: * 表示允许来自任何域的请求,当然了也可以进行一个IP的限制,限制在某个域名之下才能够访问,有如下形式:
res.setheader("Access-Control-Allow-Orgin":"*");
res.setheader("Access-Control-Allow-Orgin":"http://mp.csdn.net");
Access-Control-Allow-Headers
默认情况下,cors仅支持客户端向浏览器发送这(Accept、Accept-Language、Content-Langage、DPR、Downink、Save-Data、Viewport-Width、Width、Content-Type[value:text/plain、multipart/from-data、application/x-www-form-urlencded])9个请求头,如果客户端向服务器发送了额外的请求消息,则需要在服务器端通过Access-Control-Allow-Headers 对额外的请求进行声明,否则会请求失败;如下需要进行其他请求头设置:
res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header')
Access-Control-Allow-Methods
默认情况下,CORS仅支持客户端发起GET、POST、HEAD请求,如果客户端希望通过PUT、DELETE等方式请求服务器资源,则需要在服务器端,通过Access-Control-Allow-Methods来指明实际请求所允许使用的HTTP方法;
// 只允许post,get,head,delete
res.setHeader('Access-Control-Allow-Methods','POST,GET,HEAD,DELETE');
// 允许所有请求方式
res.setHeader('Access-Control-Allow-Methods','*');
cors请求分为两种:简单请求和预检请求
GET / POST / HEAD 这三种任意一种请求方式,同时HTTP头部信息不超过以下几种字段:无自定义头部字段、Accept、Accept-Language、Content-Langage、DPR、Downink、Save-Data、Viewport-Width、Width、Content-Type[value:text/plain、multipart/from-data、application/x-www-form-urlencded]
请求除了 GET/POST/HEAD 这三种的其他请求METHOD类型,请求头包含自定义头部字段,向服务器发送application/json的数据;
在浏览器与服务器进行正式通信之前,浏览器会先发送OPTION请求进行预检,以获得服务器是否允许该实际请求,所以这次的OPTION请求称为 "预检请求",服务器成功响应预检请求后,才会发送真实的请求且携带真实数据。
区别:
在简单请求中,客户端与服务器之间只发生一次请求,而在预检请求中,客户端与服务器之间发生两次请求,OPTION预检请求成功之后才会发起真正的请求;
下面来进行测试:
1. 编写代码:
Document
// Express - /routes/index.js
const express = require('express');
const router = express.Router();
router.get('/get',function(req,res){
res.send('success');
})
router.delete('/del',function(req,res){
res.send({
status:0,
msg:'success'
})
})
module.exports = router;
通过执行node命令将服务器启动:
通过编写request.html模拟客户端来点击按钮发起对应的请求:
(Chrome谷歌浏览器)
(Firefox火狐浏览器)
以上就是关于cors中间件的知识和解决跨域问题的全部内容了,下面来讲另外一种跨域方式JSONP.
在前面中讲到了浏览器中的同源策源,需要访问的协议,域名和端口号要一致才能够进行跨域,但在HTML中,用过