首页 > 编程知识 正文

跨域是设置前端还是设置后端,前端跨域的几种方式

时间:2023-05-04 12:58:59 阅读:46786 作者:3766

1 .是否要引入问题1.1? 是域间吗? 跨域是指一个域下的文档或脚本试图请求另一个域下的资源,其中的跨域是广义的

1.2广义域遍历1 )资源跳转: a链接、重定向、表单提交

2 )资源嵌入:外链,如链接标签、脚本标签、img标签、框架标签等dom标签

3 )脚本请求: js的ajax请求、dom和js对象的域间操作等

1.3大跨域我们所说的跨域是指大跨域。 使用和限制浏览器同源策略的要求场景1.4同源策略同源策略是浏览器最核心、最安全的功能。 如果浏览器缺乏相同策略,则容易受到XSS、CSFR等攻击。 同源是指“协议域名端口”三者相同,只要有一个不同,就是非同源的。 同源策略限制以下行为

1 )当前域下的js脚本无法访问其他域下的cookie、本地存储等

2 )当前域下的js脚本无法访问和操作另一个域下的DOM

3 )无法发送ajax请求2 )域间解决方案0 )通过本地主机进行设置

基于jsonp的跨域

通过document.domian iframe

在window.name iframe中穿越域

在localion.hash iframe中穿越域

5.psot消息跨域

5 .域间资源共享(CORS ) )。

6.nginx代理的域之间

7.nodejs中间代理域之间

8 .网络套接字协议域之间

2.1在本地主机配置中实现域间axdyl前后的端点进行开发时,前端只需要开发时服务器所需的数据,实际部署时,在同一个域下部署不会出现域间问题。 前端开发人员只需要更改本地主机配置,并将本地默认域映射到服务器地址

2.2通过jsonp跨域、jsonp跨域实质动态编写脚本标记,可以在script标记的src属性下请求带参数的网址实现跨域通信

1.scriptfunctionhandleresponse (RES ) response代码操作console.log JSON.stringify (RES ) }/scriptscriptwindow的本机实现btwindow //script.type=' text/JavaScript '//将回调函数handleCallback传递给后端,并在后端返回时在此前端定义的回调函数script . 便于运行vou ban.com q=JavaScript count=1callback=handle response ' document.head.appendchild (script ) }/script sarther 返回时,运行前端设置的回调函数Handelchild。 ((返回时为前端设置的回调函数h

handle callback (status 65: true,name65:admin )2.jquery实现在jQuety包的$.ajax中具有dataType属性,并将该属性设置为" jQuety "

script src=' https://cdn.bootcdn.net/Ajax/libs/jquery/3.5.1/jquery.js '/script script type=' text/javasc URL : ' https://API.douban.com/v2/book/search ',type: 'GET ',JSON3360'caax //默认dataType: 'jsonp 指定覆盖//返回的数据类型的查询参数名称,并设置JONP方式jsonp callback : ' handle response ',//回调函数名称data3360{q: status,xhr ) { console.log )状态为“status”状态为“xhr.statusText”)的console.log(RES

ponse) } }) }) })</script> 3. vue.js //vue.js this.$http.jsonp({ params:{}, jsonp:'handleCallback' }).then( (res)=>{ console.log(res) } ) 4. jsonp实现跨域总结

由于jsonp实现的跨域原理是动态尝试script标签,利用script标签的src不受同源策略的限制,但是使用jsonp的缺点是只能实现get请求,不能实现post请求;

2.3 资源共享跨域(CORS) 普通的跨域请求:(即get、post)
就是只要服务器配置即可,前端不需要配置,若需要携带cookie,那么前后端都需要配置(注意:这个cookie为跨域请求接口所在域的cookie) 1.前端设置:

1)使用的时原生ajax

//前端设置是否携带cookiexhr.withCredentials=true

示例代码:

var xhr=new XMLHttpRequest(); //前端设置是否允许携带cookie xhr.open('get','http://www.domain2.com:8080/login',true) xhr.setRequestHeader('Content-type','appliction/x-www-form-urlencoded'); xhr.onreadystatechange=function(){ if(xhr.readyState!==){ return; } else{ if(xhr.status>=200&&xhr.status<300){ console.log(xhr.responseText) } } }

2)使用vue框架

a) 可以使用axios设置: axios.default.withCredentials=true; vue-resource设置: Vue.http.options.credentials=true 2.后端设置

1)Java后台示例

/* * 导入包:import javax.servlet.http.HttpServletResponse; * 接口参数中定义:HttpServletResponse response */// 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com"); // 允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示response.setHeader("Access-Control-Allow-Credentials", "true"); // 提示OPTIONS预检时,后端需要设置的两个常用自定义头response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");

2)Nodejs后台示例

var http = require('http');var server = http.createServer();var qs = require('querystring');server.on('request', function(req, res) { var postData = ''; // 数据块接收中 req.addListener('data', function(chunk) { postData += chunk; }); // 数据接收完毕 req.addListener('end', function() { postData = qs.parse(postData); // 跨域后台设置 res.writeHead(200, { 'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie 'Access-Control-Allow-Origin': 'http://www.domain1.com', // 允许访问的域(协议+域名+端口) /* * 此处设置的cookie还是domain2的而非domain1,因为后端也不能跨域写cookie(nginx反向代理可以实现), * 但只要domain2中写入一次cookie认证,后面的跨域接口都能从domain2中获取cookie,从而实现所有的接口都能跨域访问 */ 'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly的作用是让js无法读取cookie }); res.write(JSON.stringify(postData)); res.end(); });});server.listen('8080');console.log('Server is running at port 8080...');

总结:

后端配置Access-Control-Allow-Origin,来设置允许访问的域,或者配置*表示全部允许;当有多个请求需要跨域时或者多台浏览器需要跨域反问时,那么此时只能配置为 *,但是此时带来的问题是,不能携带cookie只有设置允许特定的源访问时,才能携带cookie 2.4 nginx反向代理实现跨域

具体使用参考:nginx反向代理接口跨域
使用nginx配置反向代理总结:
1)实现思路:通过配置一个代理服务器(域名与本地浏览器相同,这里举例为domain1,端口不同,比如本地浏览器端口为80,那么你可以配置81或者其他),这个代理服务器作为跳板机,反向代理访问服务器的接口(这里举例为domain2)
2)使用nginx配置反向代理实现跨域不需要服务器的配合,不过需要你搭建一个中转nginx服务器,用于转发请求;
3)使用nginx反向代理可以实现修改cookie中domian信息,方便当前域cookie写入,实现跨域登录

nginx具体配置 #proxy服务器server { //端口号 listen 81; //域名 server_name www.domain1.com; location / { proxy_pass http://www.domain2.com:8080; #反向代理 proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名 index index.html index.htm; # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用 add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为* add_header Access-Control-Allow-Credentials true; }}

前端代码示例 var xhr = new XMLHttpRequest();// 前端开关:浏览器是否读写cookiexhr.withCredentials = true;// 访问nginx中的代理服务器xhr.open('get', 'http://www.domain1.com:81/?user=admin', true);xhr.send(); nodejs后端示例 var http = require('http');var server = http.createServer();var qs = require('querystring');server.on('request', function(req, res) { var params = qs.parse(req.url.substring(2)); // 向前台写cookie res.writeHead(200, { 'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本无法读取 }); res.write(JSON.stringify(params)); res.end();});server.listen('8080');console.log('Server is running at port 8080...'); 2.5 Nodejs中间层代理跨域 2.4.4 vue框架中实现跨域 即是利用node+webpack+webpack-dev-server代理接口跨域,在开发环境中,由于vue的渲染服务和代理服务都是webpack-dev-server同一个,所以页面与代理之间不再跨域,无需设置headers跨域信息了;使用vue脚手架搭建的项目,在项目的config目录下的index文件中进行代理配置
注意:只是用于生成环境
对于生成环境和开发环境中配置的代理实现跨域参考文章:通过vue dev和nginx反向代理实现开发环境和生成环境跨域https://www.cnblogs.com/wasbg/p/10973880.html
举例如下: proxyTable: { '/api': {//匹配所有以‘/api’开头的请求路径 target: 'http://localhost:4000',//代理目标的基础路径(即后端的额接口地址) changeOrigin:true,//是否允许跨域 pathRewrite:{ //重写路径:去掉路径中开头的‘/api’ '^/api':''//这个根根据真正的需求而定 } } },


配置说明:

代理设置完成之后,会检查请求头是否与代理映射相符,不符合则不走代理;当匹配到映射路径时就会进入代理,并将target属性补全到请求路径当我们遇到压迫访问多个接口时,我们可以为每个服务器配置不同的代理,以映射路径作为区分,比如所加的‘/api’是为了区分是否该路径是否向服务器发送异步请求,但是‘/api’并非真实存在与服务器的地址中的,因此我们需要利用pathRewrite属性对所映射的‘/api’/部分进行重写;通俗的将就是axdyl需要向后端发送跨域请求时,那么根据不同的数据,肯定有不同的请求地址,若后端没有统一加某以标识符,那么在前端你可以自己所配置的代理匹配,然后再通过pathRewrite属性将你所加的‘/api’(并不是真实存在的)删除掉即还原真实的请求地址 2.6 使用WebSocket协议跨域 使用WebSocket协议,这个协议没有同源限制

参考文章:

https://segmentfault.com/a/1190000011145364

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。