文章目录

  • 前言
    • 跨域解决的方法
      • 1.JSONP
      • 2.CORS跨域资源共享
      • 3.http proxy => webpack webpack-dev-server
      • 4.nginx反向代理
      • 5.postMessage(跟Worker很像)
      • 6.WebSocket协议跨域
  • 总结

前言

为了加快请求响应时间,服务器进行分布式布局,将服务器分为:
web服务器:用于处理静态资源
data服务器:业务逻辑和数据分析
图片服务器

由于浏览器的同源策略,同源策略认为以下三者都一样就是同源,只要有一个不同就是跨域:

  • 协议
  • 域名
  • 端口号

导致需要用到跨域请求。

跨域解决的方法

1.JSONP

使用不存在跨域请求的限制的html标签发送get请求,比如以下标签:
-script
-img
-link
-iframe

jsonp实现:

服务器:

let express = require('express'),app = express();app.listen(8001, () => {console.log("OK!");
})app.get('/list', (req, res) => {let { callback = Function.prototype } = req.query;let data = {code: 0,message: "珠峰培训"};res.send(`${callback}(${JSON.stringify(data)})`)
})

客户端:

<!DOCTYPE html>
<html>
<head><title>GoJSONP</title>
</head><body>
<script type="text/javascript">function jsonhandle(data){alert("age:" + data.age + "name:" + data.name);}</script><script crossorigin="anonymous" integrity="sha384-rY/jv8mMhqDabXSo+UCggqKtdmBfd3qC2/KvyTDNQ6PcUJXaxK1tMepoQda4g5vB" src="https://lib.baomitu.com/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript">$(document).ready(function(){var url = "http://127.0.0.1:8001/list?callback=jsonhandle";var obj = $('<script><\/script>');obj.attr("src",url);$("body").append(obj);});</script>
</body>
</html>

结果:

问题:JSONP只能支持GET请求。

2.CORS跨域资源共享

做法:

1.客户端(发送ajax/fetch请求)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script src = "./node_modules/_axios@0.21.1@axios/dist/axios.js"></script><script>axios.get('http://127.0.0.1:3001/list').then(result =>{console.log(result);})</script></body></html>

2.服务器端设置相关的头信息(需要处理options试探性请求)

let express = require('express'),app = express();app.use('*', function (req, res, next) {res.header('Access-Control-Allow-Origin', '*'); //这个表示任意域名都可以访问,这样写不能携带cookie了。为了保证安全//res.header('Access-Control-Allow-Origin', 'http://www.baidu.com'); //这样写,只有www.baidu.com 可以访问。res.header('Access-Control-Allow-Credentials', true);res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');//设置方法if (req.method == 'OPTIONS') {res.send(200); // 意思是,在正常的请求之前,会发送一个验证,是否可以请求。}else {next();}
});app.listen(3001, () => {console.log("OK!");
})app.get('/list', (req, res) => {let data = {code: 200,message: "我是服务器的数据!"};res.send(data)
})

3.http proxy => webpack webpack-dev-server

我们配置如下:
webpack.config.js

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {mode: "production",entry: './fun.js',output: { // 输出配置filename: './built.js', // 输出文件名path: resolve(__dirname, 'build/js') // 输出文件路径配置},plugins: [new HtmlWebpackPlugin({template: './please.html',filename: 'index.html'})],devServer: {port: 3000,progress: true,contentBase: './build',open: true// proxy: {//   '/': {//     target: 'https://www.baidu.com/',//     changeOrigin: true//   }// }}
}

fun.js如下:

import axios from "axios"axios.get('https://www.baidu.com/').then(res => {console.log(res);
})

打开webpack内置的服务器: npx webpack-dev-server。

会发生跨域,那么我们需要把devServer上的proxy注释去掉。就可以了。

这是Node中间件 代理实现的!

就是用Node来搭了一个代理服务器帮忙转发客户端的请求??毕竟服务器和服务器不存在跨域。

如果要发行呢??毕竟devServer 是方便我们调试。那么就需要用node来做代理了。

4.nginx反向代理

不需要前端干啥。其实就是nginx帮我们加了Access-Control-Allow-Origin的请求头啦。

5.postMessage(跟Worker很像)

我们先看看postMessage由谁来调用:

语法

otherWindow.postMessage(message, targetOrigin, [transfer]);
  • otherWindow

    其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

另外一种说法是:

otherWindow

对将接收消息的窗口的引用。获得此类引用的方法包括:

  • Window.open (生成一个新窗口然后引用它),
  • Window.opener (引用产生这个的窗口,返回打开当前窗口的那个窗口的引用,例如:在window A中打开了window B,B.opener 返回 A.),
  • HTMLIFrameElement.contentWindow<iframe>从其父窗口引用嵌入式),
  • Window.parent(从嵌入式内部引用父窗口<iframe>
  • Window.frames +索引值(命名或数字)。

或者看看MDN上描述:

window.postMessage MDN

otherWindow.postMessage(message, targetOrigin, [transfer])
otherWindow: A reference to another window(发送方的引用)

message:Data to be sent to the other window.(要发送到接受方的数据)

targetOrigin:Specifies what the origin of otherWindow must be for the event to be dispatched(接收方的 源,还有必须要有监听message事件)

使用:

我们先建立两个不同源的服务器:

let express = require('express'),app = express();app.use(express.static('./'));app.listen(1001, () => {console.log("port of 1001 OK!");
})
let express = require('express'),app = express();app.use(express.static('./'));app.listen(1002, () => {console.log("port of 1002 OK!");
})

1001.html,这个文件跑在域名为127.0.0.1:1001的服务器上,用于向域名为127.0.0.1:1002的服务器发送数据:

<!DOCTYPE html>
<html lan上g="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
fuwfuq
<body><h1>server1</h1><iframe id="myframe" src="http://127.0.0.1:1002/1002.html" frameborder="0"></iframe><script>myframe.onload = function () { //注意要onload之后,才可以用postMessagelet iframeWindow = myframe.contentWindow;iframeWindow.postMessage("宁静致远", "http://127.0.0.1:1002/1002.html");}//监听B传递的信息window.onmessage = function (ev) {console.log(ev.data);}</script></body></html>

这里有个需要注意的问题,我们 发送方的引用,即调用postMessage() 那个引用的源要与接受方的源即postMessage()的第二的参数 要同源。

1002.html,这个文件跑在域名为127.0.0.1:1002的服务器上,用于向域名为127.0.0.1:1001的服务器发送和接收数据:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><h1>server2</h1><script>//监听A发送过来的信息window.onmessage = function (ev) {console.log("server2 recevice message");ev.source.postMessage("recevice message", ev.origin);}</script>
</body></html>

结果:

这种方法本质是在一个页面上通过iframe标签打开不同源的其它页面,通过主页面与iframe交流的方法postMessage进行数据的交流。可以进行get和post请求。

6.WebSocket协议跨域


总结

前端跨域方案可以分为4个方向:

  1. 通过没有同源策略限制的Html标签实现数据请求。
  2. 在客户端建一个服务器代理。
  3. 请求加上access-control-change- 请求头。
  4. 使用websocket协议。

前端跨域方案看这篇就够了相关推荐

  1. java fileupload上传附件到服务器,可携带参数(简单易用)可跨域,看这篇就够了

    一个很简单实用的上传附件实例 首先主要用到的包: 先看服务端代码,我这里是用了Servlet,在web.xml配置 <servlet><servlet-class>com.fi ...

  2. 前端跨域请求get_(单点登录)跨域SSO看这篇文章就够了:前端篇

    前言 前俩篇文章,我们从概念,聊到了服务器中设计的内容.不知道大家是否觉得通俗易懂呢? 接下来的内容则有些偏向前端部分. 正文 三.Cookie传递 3.1.通过URL参数实现跨域信息传递 我们要在A ...

  3. Spring Cloud Gateway CORS 方案看这篇就够了

    欢迎关注方志朋的博客,回复"666"获面试宝典 在 SpringCloud 项目中,前后端分离目前很常见,在调试时,会遇到两种情况的跨域: 前端页面通过不同域名或IP访问微服务的后 ...

  4. 前端跨域问题汇总及解决方案

    "关注  前端开发社区 ,回复" 1" 即可加入  前端技术交流群,回复  " 2" 即可免费领取500G前端干货! 来源 | https://seg ...

  5. 解决前端跨域的几种方法

    解决前端跨域的几种方法 了解跨域出现的原因 解决跨域的几种方法 想要解决跨域 先要知道为什么会出现跨域 跨域:指的是浏览器不能执行其他网站的脚本 它是由浏览器的同源策略造成的 是浏览器对javascr ...

  6. 9种常见的前端跨域解决方案

    9种常见的前端跨域解决方案(详解) 2019.09.02 21:54 73879浏览 一.什么是跨域?   在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制. ...

  7. 前端战五渣学前端——跨域

    跨域(Cross-Origin) 这几年的工作.面试中,还遇到一个不能回避的问题,那就是跨域,一般面试的时候会问你'怎么解决跨域问题','跨域是什么','为什么会有跨域'等类似的问题.前段时间后端大佬 ...

  8. 聊聊前端跨域的爱恨情仇

    今天是过完春节以后的第二周啦,而我好像终于回到正常工作的状态了呢,因为突然间就对工作产生了厌倦的情绪,Bug就像无底洞一样吞噬着我的脑细胞.人类就像一颗螺丝钉一样被固定在整部社会机器上,除了要让自己看 ...

  9. 前端跨域jsonp的细节,挡住面试官的连环提问

    1.前言 在前端面试中,想必每一个人都会被问到跨域相关的问题,背过八股文的小伙伴肯定对跨域的解决对答如流,常见的跨域解决方案在网上有很多整理,但是如果问到实现的细节,你是否能够手写实现或者深入解读呢? ...

最新文章

  1. Linux之文档与目录结构
  2. CRC32算法详细推导(2)
  3. Spring Boot项目优雅的全局异常处理方式(全网最新)
  4. “抱大腿”的正确姿势
  5. 利用Diskgen找回分区破坏前的资料
  6. SQL Server触发器创建、删除、修改、查看
  7. xlc mysql_mysql – 用于存储产品信息的noSQL?
  8. 解决Conda install tensorflow弹窗Python.exe已经停止工作的问题
  9. 哪种修复redis未授权访问漏洞的方法是相对不安全的_redis漏洞复现
  10. 3S基础知识:MapX应用教程—创建地图对象
  11. VS2017+OpenCV4.1.0(VC15)、VS2015+OpenCV3.4.1(VC14) 配置
  12. 推荐的五款市面上常用的免费CMS建站系统
  13. Linux 服务器配置 ASF 云挂卡
  14. python自动输入支付密码_python接入支付宝的实例操作
  15. 量子计算机原理以及量子算法
  16. 汇编语言clr c什么意思,汇编程序中C(1):errorC129:missing';'before Bit是什么意思,加了分号也不对,怎么回事啊...
  17. Python爬取新冠肺炎疫情实时数据(丁香园)
  18. 同元车辆模型库——TA系列
  19. 组策略部署Office 2007
  20. 外卖返利小程序系统公众号外卖饿了么美团cps返利小程序分销系统

热门文章

  1. spring boot Activitymq topic与 queue 并存实现方案
  2. 基于SSM水果蔬菜商城批发网站|电商购物系统
  3. 【高速接口-RapidIO】3、RapidIO串行物理层的包传输过程
  4. 20190802中山晨考 考试心态
  5. 强缓存和弱缓存是什么
  6. 《深入理解Java虚拟机》读书笔记(二)--自动内存管理机制
  7. ffmpeg使用参数介绍
  8. 华为手机 打开html,华为手机开发者选项的利与弊!有些设置最好不要打开
  9. 情报分析师助力打破大数据泡沫
  10. [健康]那到底有哪些食物吃了会让我们易长皱纹呢?