网站建设注意问题,济南高新区网站建设,阅读网站策划书,加拿大28网站开发前端跨域2
前端跨域解决方案#xff08;11种方案#xff09;
1.JSONP跨域解决方案的底层原理
script、img、link、iframe...script srchttps://cdn.bootcss.com/jquery/3.4.1/core.js/script// 这个就是因为script标签没有跨域限制#xff0…前端跨域2
前端跨域解决方案11种方案
1.JSONP跨域解决方案的底层原理
script、img、link、iframe...script srchttps://cdn.bootcss.com/jquery/3.4.1/core.js/script// 这个就是因为script标签没有跨域限制所以才能成功请求加载。react中子组件想要修改父组件中的状态也是传递一个回调函数给父组件这个思想和JSONP的思想是一致的。
JSONP需要服务器的支持问题JSONP只能处理GET请求放在后面不安全服务器返回的数据只在浏览器会直接执行如果是木马修改也会直接执行不安全
举例 html页面 1.jsonp.html
!DOCTYPE html
htmlheadmeta charsetUTF-8meta http-equivX-UA-Compatible contentieedgemeta nameviewport contentwidthdevice-width, user-scalableno, initial-scale1.0
/headbodyscript srchttps://cdn.bootcss.com/jquery/3.4.1/jquery.min.js/scriptscript src./1.jsonp.js/script
/body/html1.jsonp.js
$.ajax({url: http://127.0.0.1:8001/list,method: get,dataType: jsonp, //执行的是JSONP的请求,这是jquery封装的ajax的功能success: res {console.log(res);}
});服务端配合serverJSONP.js:
let express require(express),app express();
app.listen(8001, _ { // 监听8001端口console.log(OK!);
});
app.get(/list, (req, res) {let {callback Function.prototype // callback如果没有默认为空的函数} req.query;let data {code: 0,message: 返回jsonp请求的结果};res.send(${callback}(${JSON.stringify(data)})); //后端需要处理好这样的数据格式
});2. CORS跨域资源共享
客户端正常发送请求服务端设置相应的头信息。
客户端发送ajax/fetch请求
axios.defaults.baseURL http://127.0.0.1:8888;
axios.defaults.withCredentials true;
axios.defaults.headers[Content-Type] application/x-www-form-urlencoded;
axios.defaults.transformRequest function (data) {if (!data) return data;let result ;for (let attr in data) {if (!data.hasOwnProperty(attr)) break;result ${attr}${data[attr]};}return result.substring(1);
};
axios.interceptors.response.use(function onFulfilled(response) {return response.data;
}, function onRejected(reason) {return Promise.reject(reason);
});
axios.defaults.validateStatus function (status) {return /^(2|3)\d{2}$/.test(status);
}服务器设置相应的头信息需要处理options试探性请求
app.use((req, res, next) {res.header(Access-Control-Allow-Origin, http://localhost:8000); // http://localhost:8000是允许跨域请求的地址如果允许很多地址跨域请求设置为*//*就不能在允许携带cookie了 具体地址res.header(Access-Control-Allow-Credentials, true);res.header(Access-Control-Allow-Headers, Content-Type,Content-Length,Authorization, Accept,X-Requested-With);res.header(Access-Control-Allow-Methods, PUT,POST,GET,DELETE,HEAD,OPTIONS);if (req.method OPTIONS) {res.send(OK!);return;}next();
});3.基于http proxy实现跨域请求
http proxy webpack webpack-dev-server 修改webpack.config.js
let path require(path);
let HtmlWebpackPlugin require(html-webpack-plugin);
module.exports {mode: production,entry: ./src/index.js,output: {filename: bundle.min.js,path: path.resolve(__dirname, build)},devServer: {port: 3000,progress: true,contentBase: ./build,proxy: { // 以/开始的请求就把请求路径转到 target/: {target: http://127.0.0.1:3001,changeOrigin: true // 允许跨域}}},plugins: [new HtmlWebpackPlugin({template: ./src/index.html,filename: index.html})]
};4. 基于post message实现跨域处理
postMessage方法允许来自不同源的脚本采用异步方式进行有限的通信可以实现跨文本档、多窗口、跨域消息传递。 https://developer.mozilla.org… A页面
iframe srchttp://www.github.com/B.html/iframe
scriptlet iframe document.querySelector(iframe);// onload 事件会在页面或图像加载完成后立即发生, iframe 中的onload事件会在整个文档加载完成后执行。iframe.onload function () {iframe.contentWindow.postMessage(github, http://www.github.com/);// http://www.github.com/ 接受 github 参数}window.onmessage function (ev) {console.log(ev.data);}
/scriptB 页面
// 接收方监听message事件
window.onmessage function (ev) {console.log(ev.data);ev.source.postMessage(ev.data, ev.origin);
}** 5. nginx反向代理 不需要前端做什么
www.github.cn - www.github.com
#proxy服务器
server {listen 80;server_name www.github.com;location / {proxy_pass www.github.cn; #反向代理proxy_cookie_demo www.github.cn www.github.com;add_header Access-Control-Allow-Origin www.github.cn;add_header Access-Control-Allow-Credentials true;}
}** 6. 基于 iframe 的跨域解决方案**
三种window.name / document.domin / location.hash
① window.name iframe 页面A
let proxy function(url, callback) {let count 0;let iframe document.createElement(iframe);iframe.src url;iframe.onload function() {if(count0){iframe.contentWindow.location http://www.github.cn/proxy.html;count;return;}callback(iframe.contentWindow.name);};document.body.appendChild(iframe);
};//请求跨域B页面数据
proxy(http://www.github.cn/B.html, function(data){alert(data);
});B页面
window.name github;proxy.html是空页面
② location.hash iframe A和C同源 A和B非同源
A页面
iframe idiframe srchttp://127.0.0.1:1002/B.html styledisplay:none;/iframe
scriptlet iframe document.getElementById(iframe);//向B.html传hash值iframe.onloadfunction(){iframe.src http://127.0.0.1:1002/B.html#msggithub;}//开放给同域C.html的回调方法function func(res) {alert(res);}
/scriptB 页面
iframe idiframe srchttp://127.0.0.1:1001/C.html styledisplay:none;/iframe
scriptlet iframe document.getElementById(iframe);//监听A传来的HASH值改变再传给C.htmlwindow.onhashchange function () {iframe.src http://127.0.0.1:1001/C.html location.hash;}
/scriptC页面
script//监听B传来的HASH值window.onhashchange function () {//再通过操作同域A的js回调将结果传回window.parent.parent.func(location.hash);};
/script③ document.domain iframe 只能实现同一主域不同子域之间的操作 v.qq.com sports.qq.com 父页面A http://www.github.cn/A.html
iframe srchttp://school.github.cn/B.html/iframe
scriptdocument.domain github.cn; // 相同的主域名var user admin;
/script子页面B http://school.github.cn/B.html
scriptdocument.domain github.cn;alert(window.parent.user);
/script** 7. WebSocket 协议跨域** 前端处理
script src./socket.io.js/script
scriptlet socket io(http://127.0.0.1:3001/);//连接成功处理socket.on(connect, function() {//监听服务端消息socket.on(message, function(msg) {console.log(data from server: msg); });//监听服务端关闭socket.on(disconnect, function() { console.log(server socket has closed!);});});//发送消息给服务器端socket.send(github);
/script服务器端处理
//监听socket连接server是服务器创建的服务
socket.listen(server).on(connection, function(client) {//接收信息client.on(message, function(msg) {//msg客户端传递的信息//...client.send(msg);});//断开处理client.on(disconnect, function() {console.log(client socket has closed!);});
});