node js解决 CORS 跨域问题(完整实例)

node js 解决 CORS 跨域

一、本篇学前了解

  1. 那些情况不会有跨域?

    ajax同源策略( 协议 主机(ip 域名) 端口相同)

​ 同一个服务器下不会有跨域问题

​ 服务器请求服务器没有跨域问题

  1. 什么是OPTIONS请求?

    浏览器在某些请求中,在正式通信前会增加一次HTTP查询请求,称为"预检"请求(preflight)

    览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。

    只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错

    (一般你看你请求一次会有2次network返回,其中一个请求方式就是OPTIONS)

  2. toLowerCase() 方法用于把字符串转换为小写

  3. 以下配置都是在server.js中

二、解决跨域

1.利用中间件 cors

安装 npm i cors -S

使用方式一 : 为所有源启用跨域

const  cors = require('cors')
 app.use(cors())
 app.listen(8000, function () {
   console.log('start')
 })

使用方式二 : 按条件配置

 var express = require('express')
 var cors = require('cors')
 var app = express()
 var whitelist = ['http://example1.com', 'http://example2.com']
//  异步配置
  var corsOptions;
 var corsOptionsDelegate = function (req, callback) {
  if (whitelist.indexOf(req.header('Origin')) !== -1) {
    corsOptions = { origin: true} //在CORS响应中反映(启用)请求的起源
  } else {
     corsOptions = { origin: false} // 拦截请求
  }
  callback(null, corsOptions) //  error  options
}

 app.all("*", cors(corsOptionsDelegate), function (req, res, next) {
 if(corsOptions.origin  === true){
    if (req.method.toLowerCase() == 'options'){
      res.sendStatus(200);  //让options尝试请求快速结束
     }
     else{
      next();
     }
   } else {
    res.sendStatus(500); //被拦截
   }
 })
  app.post('/cors',(req,res)=> {
  res.send('ok')
})
 app.listen(8000, function () {
   console.log('start')
 })
2.只使用路由的拦截实现

使用方式一 : 为所有源启用跨域

//  方式二 通过app路由的拦截
const express = require('express')
//express 实例化
const app = express()
// 所有请求都经过这里
app.all("*",function(req,res,next){
    // 防止undefined 报错
  if(!req.headers.origin){
    return
  }
     //设置允许跨域的域名,*代表允许任意域名跨域
     res.header("Access-Control-Allow-Origin","*");
    //  例如 允许百度跨域, 把上面这行的*替换为 https://baidu.com
     //允许的header类型
     res.header("Access-Control-Allow-Headers","content-type");
     //跨域允许的请求方式 
     res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
     if (req.method.toLowerCase() == 'options'){
      res.sendStatus(200);  //让options预验证尝试请求快速结束

     }
     else{
      next();
     }
 })
  app.post('/cors',(req,res)=> {
  res.send('ok')
})
 app.listen(8000, function () {
   console.log('start')
 })

使用方式二 : 按条件配置

// 允许多个跨域
const express = require('express')
//express 实例化
const app = express()
// 所有请求都经过这里
app.all("*",function(req,res,next){
  var orginList=[
      "http://www.bibi.com",
      "http://www.qq.com",
      "http://www.baidu.com"
  ]
  // 防止undefined 报错
  if(!req.headers.origin){
    return
  }
   if(orginList.includes(req.headers.origin.toLowerCase())){
    //允许的header类型
res.header("Access-Control-Allow-Headers", "content-type");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin",req.headers.origin);
    if (req.method.toLowerCase() == 'options'){
      res.sendStatus(200);  //让options尝试请求快速结束
    }
    else{
      next();
    }
} else {
  res.sendStatus(500)
}
})
  app.post('/cors',(req,res)=> {
  res.send('ok')
})
 app.listen(8000, function () {
   console.log('start')
 })
3.前端使用服务器代理

用node在本地搭建一个服务器, ajax请求自己搭建的node服务器

在node中请求 后端的服务器

安装 npm i request -S

const express = require('express')
//解析post消息体的插件
const request = require('request');
const bodyParser = require('body-parser')
//express 实例化
const app = express()
//使用中间件
//bodyParser.urlencoded 解析表单
app.use(bodyParser.urlencoded({
  extended: false
}))
//解析json
app.use(bodyParser.json())
//自己的请求的接口
app.get('/cors',(req,res)=>{
    //请求后端接口的地址
  request('http://www.google.com', function (error, response, body) {
  if(error){
    console.log('error:', error); 

  }  else {
    console.log('body:', body); 
    res.send(body)
  }
});
})
app.listen(8000, () => { //监听8000端口,开启服务
  console.log('server start');
})
发布了52 篇原创文章 · 获赞 82 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/marendu/article/details/103257186
今日推荐