cors解决ajax跨域问题

必须是下面定义对CORS安全的首部字段集合,不能是集合之外的其他首部字段。
Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save-Data、Viewport-Width、Width。

Content-Type的值必须是text/plain、multipart/form-data、application/x-www-form-urlencoded中任意一个值

满足上面所有的条件才不会发送预检请求,在实际项目中我们的请求格式可能是application/json格式编码,或者使用自定义请求头都会触发CORS的预检请求。

所以,在项目中是否会触发CORS的预检请求要做到心中有数。

<!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>
    <h3>端口号3000页面</h1>
    <button>发送同源请求</button>
    <button>发送跨域请求</button>
    <!-- <form action="" enctype="application/x-www-form-urlencoded"></form> -->
<script>
    let but = document.querySelectorAll("button")
    // 同源状态下请求
    but[0].onclick = function(){
        let xhr = new XMLHttpRequest();
        xhr.open("post","/post",true) //路径这里相对路径
        xhr.onload = function(){
           console.log(xhr.responseText) 
        }
        xhr.send()
    }

    // 跨域请求 3000的页面请求4000的服务器
    but[1].onclick = function(){
        let xhr = new XMLHttpRequest();
        // xhr.open("post","http://localhost:4000/post?cd=cbdata",true)
        xhr.open("post","http://localhost:4000/post",true)
        
        // post请求s设置头部 记不住可以敲form enctype 虽说默认尽量设置上
        // xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        // // 3.与后端的3相对应                 这里传json 下面的数据也得转JSON
        xhr.setRequestHeader("Content-type","application/json")
        xhr.setRequestHeader("test","some vlaue...")     
        
        // 5允许跨域请求携带凭证,访问的服务端也得设置,凭证是放在请求头里的,cookie是凭证之一
        // 两个问题 1预检请求 2.允许前段设置头部信息
        // 预检请求出现情况 1指定的请求类型options
        // 2.修改了指定的属性(详情见文档)3.修改了指定的属值(详情见文档)
        xhr.withCredentials = true;
        xhr.onload = function(res){
            console.log(xhr.responseText)    
            console.log(xhr.getAllResponseHeaders()) //输出设置的头部信息
        }
        let data = {
            name:"张三"
        }
        xhr.send(JSON.stringify(data)) //设置响应头 后端输出{ 'name ': ' 张三' }是个对象
        // 没有设置响应头 后端输出 "name = 张三"
    }

    function cbdata(){
        console.log("good")
    }
</script>
</body>
</html>
3000的服务端设置
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");

let app = new Koa();
let router = new Router();
app.use(static(__dirname+"/static"));

router.get("/",ctx=>{
    ctx.body ='hello';
})

router.post("/post",ctx=>{
    ctx.body ='http3000';
})
// 在3000里设置cookie,在页面访问的话 会设置cookie成功,
// 点击页面发送同源请求,在浏览器Network,header中也已看到设置的cookie值
// 点击非同源按钮 没有需要去前,后端设置
router.get("/setcookie",ctx=>{
    ctx.cookies.set("username","zhuangsan",{
        maxAge:1000*60*60*24
    }); 
    ctx.body = "设置cookie"
})

app.use(router.routes());
app.listen(3000);

4000的服务端设置
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
const koaBody = require("koa-body")

let app = new Koa();
let router = new Router();
app.use(static(__dirname+"/static"));
app.use(koaBody())

router.get("/",ctx=>{
    ctx.body ='hello';
})
// 预检请求的允许 *所有的预检请求,options处理 把post中的5项允许拉过来,js功能不需要
router.options("/*",ctx=>{
    ctx.set("Access-Control-Allow-Origin","http://localhost:3000")
    ctx.set("Access-Control-Expose-Headers","Content-Type,Content-Length,Date")
    ctx.set("Access-Control-Expose-Methods","GET POST DELETE HEAD OPTIONS")
    ctx.set("Access-Control-Allow-Headers","Content-Type,Content-Length,Authorization,test")
    ctx.set("Access-Control-Allow-Credentials",true)
    ctx.set("Access-Control-Max-Age",3600*24)
    console.log("options")
    ctx.body ='options';//随便发个数据 响应一下
})

router.post("/post",ctx=>{
    // 除了手动设置允许跨域是必须设置的,其他下面几项设置都是按需设置
    // 写到这一步算是请求成功,同源策略是浏览器行为与服务器无关
    // 跨域请求,响应数据都能成功,浏览器但是不能显示,会报错
    // 解决办法:在服务器 使用cors设置头部
    // ctx.set("Access-Control-Allow-Origin","*")
    //1:允许跨域访问 参2:允许谁 *好通配符所有网站(不安全,不能携带凭证) 
    //                                     指定访问服务器端口号
    ctx.set("Access-Control-Allow-Origin","http://localhost:3000")
    // 1这种方法没办法获取时间等...

    // 2设置允许前段获取时间
    ctx.set("Access-Control-Expose-Headers","Content-Type,Content-Length,Date")
    // let cbs = ctx.query.cb;
    // console.log(cbs);

    // 3设置允许前段发送的请求方式 GET POST DELETE HEAD OPTIONS
    ctx.set("Access-Control-Expose-Methods","GET POST DELETE HEAD OPTIONS")

    // 4.允许前段设置的头部
    ctx.set("Access-Control-Allow-Headers","Content-Type,Content-Length,Authorization,test")
    // console.log(ctx.request.body)

    // 5.允许携带凭证 true开启
    ctx.set("Access-Control-Allow-Credentials",true)

    // 6.设置预检请求的时间
    ctx.set("Access-Control-Max-Age",3600*24)

    console.log("cookie")
    ctx.body ='http4000跨域';
})


app.use(router.routes());
app.listen(4000);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jason–json

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值