前后端交互 - 跨域方式之 CORS方法 及 后端服务器代理

CORS跨域 / Nodejs中间件代理跨域

跨域:指的是浏览器行为,正常情况下是成功的,只是同源策略不允许拿数据,所以会报错。
jsonp 方式跨域,主要的负担都由前端来承担,但是无法携带参数。
cors 方式跨域,主要的负担由后端来承担,看起来较为优雅。

CORS跨域

CORS是一个W3C标准,全称是"跨域资源共享"( Cross-origin resource sharing )。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了 AJAX 只能同源使用的限制。
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨域通信。

跨域实现

准备两个后端服务器,均启动服务

  • 前端ajax 申请
    修改路由,指定访问资源地址
	let xhr = new XMLHttpRequest();
	xhr.open("post","http://localhost:4000/post",true); // 直接修改路由即可
	xhr.onload = function(){
		console.log(xhr.responseText);
		let res = xhr.getAllResponseHeaders();
		console.log(res)    
	}
	xhr.send();
  • 后端服务器 允许
    允许非同源进行访问
	router.post("/post", async ctx => { 
	    console.log((ctx.request.body)) // 接收返回的数据
	   
	    // 允许所有的端口访问 即允许跨域
	    // ctx.set("Access-Control-Allow-Origin","*"); 
	    // 1. 不安全  2. 不能设置允许携带凭证
	    // 允许指定的端口访问 
	    ctx.set("Access-Control-Allow-Origin", "http://localhost:3000");
	    
	    ctx.body = "端口号4000非同源"; // 测试数据
	    //  没有数据返回 post方式下 直接报错
	})
简单请求

受到浏览器的同源策略影响,同源状态下,cookie等存储不受到限制
但是,跨域使用时则会受到影响。

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

  • HEAD
  • GET
  • POST

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

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

前端页面准备
前端需要 获取 / 设置 信息,但需要后端来开启对应的权限
携带凭证 是指cookie为代表的存储方式

	// 允许跨域请求携带凭证 (开启)
	xhr.withCredentials = true;
	// 指定跨域链接地址
	xhr.open("post","http://localhost:4000/post",true);
	// 设置请求头
	xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xhr.setRequestHeader("Content-type","application/json");

后端服务器准备
以前端为主,前端需要什么就开启相对应的设置

    // 1 允许指定的端口访问 必须开启的设置
    ctx.set("Access-Control-Allow-Origin", "http://localhost:3000");

    // 2 允许获取头部信息(响应头部)
    ctx.set("Access-Control-Expose-Headers", "Content-Type,Content-length,Date");

    // 3 设置允许前端设置的请求方式(请求头部类型和数值)
    ctx.set("Access-Control-Allow-Headers", "Content-Type,Content-Length,test");

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

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

    // 6 设置预检请求的缓存时间 两个位置都写
    ctx.set("Access-Control-Max-Age", 36000 * 24);
非简单请求

非简单请求是那种对服务器有特殊要求的请求
比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
在实际项目中我们的请求格式可能是 application/json 格式编码,或者使用自定义请求头都会触发 CORS 的预检请求。
后端服务器准备
开启预检请求,对应的服务
但是相对应的该有的服务,不能减少

	// 处理预检请求  通用 所有的接口
	router.options("/*", ctx => {
	
	    // 1 允许所有的端口访问 允许跨域  
	    ctx.set("Access-Control-Allow-Origin", "http://localhost:3000");
	    
		// 2 允许获取头部信息(响应头部)
	    ctx.set("Access-Control-Expose-Headers", "Content-Type,Content-length,Date");	
	    
	    // 3 设置允许前端设置的请求方式(请求头部类型和数值)
	    ctx.set("Access-Control-Allow-Headers", "Content-Type,Content-Length,test");
	    	
	    // 4 设置允许前端发送请求的方式
	    ctx.set("Access-Control-Allow-Methods", "GET,POST,DELETE,HEAD,OPTIONS");
	    	
	    // 5 允许携带凭证  cookie只是其中之一
	    ctx.set("Access-Control-Allow-Credentials", true);	
	    
	    // 6 设置预检请求的缓存时间 两个位置都写
	    ctx.set("Access-Control-Max-Age", 36000 * 24);	   
	     
	    console.log("有预检请求");
	    ctx.body = "响应中..."
	    
	})

Nodejs中间件代理跨域

利用 node.js 的中间件去处理跨域,类似于
将跨域请求交给第三方,第三方去访问指定的网络,获取数据然后返回

koa-server-http-proxy

记得下载及引用服务
自身所在的服务端开启相应的设置
相对应的数据 还是要在想要跨域的路由中才能获取到

  • 自身后端设置
	const koaServerHttpProxy = require("koa-server-http-proxy"); 
	
	// 服务器端接口转发 
	app.use(koaServerHttpProxy("/api",{
	    target:"http://localhost:4000", // 跨域的指定地址
	    pathRewrite:{'^/api':''}, // 限定 跨域的条件: 以 api 开头
	    changeOrigin:true // 开启服务
	}));
  • 前端设置
	let xhr  = new XMLHttpRequest();
	xhr.open("post","/api/Serverpost",true); // 与后端的设置需要一致 api
	xhr.onload = function(){
		console.log(xhr.responseText);
	}
	xhr.send();
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值