前端跨域问题三个解决思路

同源策略: 同一个端口,一个域名,一个协议才能访问服务器;

 

Part One :  jsonp

原理:   通过script标签的src属性加载js不受同源策略控制:

首先定义一个处理数据的方法:

 const handleRequest = function (json) {
        console.log(json);
    }

注意此处的handleRequest是全局函数,如果window会被污染,建议直接添加事件格式为  window.handleRequest = ...

创建script标签:

  let _script = document.createElement("script");

添加属性上去,然后传一个回调函数过去:

  // 此处的handleRequest为全局定义的方法,用来执行接收收据后的callback
  _script.setAttribute("src",url+"?callback=handleRequest");

将script标签添加到head标签上,为什么要添加到head标签呢?怕影响到其他dom元素

document.head.appendChild(_script);

将上面的操作封装到一个方法:

    // 处理返回的请求
    const handleRequest = function (json) {
        console.log(json);
    }
    function CrossDomain(url){
        let _script = document.createElement("script");
        _script.setAttribute("src",url+"?callback=handleRequest");
        document.head.appendChild(_script);
    }
    CrossDomain("http://localhost:8080/script");

好了,客户端逻辑写好了,服务端如何配置呢?

其实原理很简单,首先获取函数名,然后request.body上传入要执行的函数的字符串形式:

此处使用koa框架进行简单演示:

const forScript = async function(ctx,next){
    let {callBack} = ctx.request.query;
    ctx.response.body = `${callBack}(333)`;
}
app.use(route.get("/script",forScript));

就可以成功了!

 

 

Part Two: CROS跨域资源请求

首先,客户端请求分为两种:

(一) 简单请求: 

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

此时服务器应该设置:

  ctx.response.set("Access-Control-Allow-Origin","*");

如果需要接收cookie,则需要设置:

ctx.response.set("Access-Control-Allow-Credentials","true");

注意,此时Access-Control-Allow-Orign就不能设置为星号了,需要设置为具体的ip;

(二)非简单请求:

   超出上面规定的请求,发送非简单请求时,浏览器会先向服务器发起预请求,方法为OPTIONS,如果确认能接受此方法后,再发起正式请求;

  此时,再进行普通的请求转发;

  如put请求,需要在koa中的路由定义options方法的处理:

app.use(route.options("/cros",async (ctx,next)=>{
    console.log("处理options");
    ctx.response.set("Access-Control-Allow-Origin","null");
    ctx.response.set("Access-Control-Allow-Credentials","true");
    ctx.response.set('Access-Control-Allow-Headers', 'Content-type');
    // 意思等同于请求执行成功,但是没有数据
    ctx.response.status = 204;
    ctx.response.set("Access-Control-Allow-Methods","POST,GET,PUT");
}));

然后定义put请求的处理:

app.use(route.put("/cros",async (ctx,next)=>{
    console.log("处理put");
    ctx.response.set("Access-Control-Allow-Origin","null");
    ctx.response.set("Access-Control-Allow-Credentials","true");
    ctx.response.body = "处理put";
}))

接着就能成功返回了!

Part Three nginx反向代理

此方法需要安装nginx服务器,让nginx将请求转发到目标要求的地址:

linux安装nginx教程

具体配置如下,首先进入到nginx.conf

cd /etc/nginx
# vi编辑脚本
sudo vi nginx.conf

修改其中的server为:

http {

        server {
        # 设置默认索引
        index g.html;
        # 设置项目所在根目录
        root /home/yangdilin/koa/;
        # 监听80端口
        listen 80;
        # nginx服务器的IP地址或域名
        server_name localhost;
        # 代理的端口
         location /api/cros {
        # 请求转发的地址
         proxy_pass http://127.0.0.1:8080/cros;
             }
        }
sudo nginx -s -reload

既可以代理成功!nginx还可以直接设置响应头Acess-Control-Allow-Origin,实现方法二的CORS,具体就不进行介绍了;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值