关于跨域的问题

同源策略

简单来说,如果以下三项:同一协议、同一域名、同一端口,有一点不满足,服务器就会报错。

解决方案

跨域问题可以说在前端方面不可避免,但同源策略毕竟在保护网络信息安全方面起到很大的作用。试想如果没有同源策略,别的网页可以轻松窃取你的cookie,而假如你的cookie中存有你的个人信息…太可怕了,不过话说回来同源策略带来的跨域问题也很头疼,幸好现在已经有多种方式能够解决

先总结一下跨域都有哪些

  1. 通过JSONP跨域
  2. document.domain + iframe 跨域 (主域相同的情况下可用)
  3. location.hash + iframe 跨域
  4. window.name + iframe 跨域
  5. postMessage 跨域
  6. 跨域资源共享 (CORS)(后台)
  7. nginx 代理跨域 (后台)
  8. node.js 中间件代理跨域 (后台)
  9. WebSocket协议跨域 (后台)

简答总结一下前端用到的几种跨域

1.JSONP跨域

jsonp原理
浏览器只对XHR(XMLHttpRequest)请求有同源请求限制,而对script标签src属性、link标签ref属性和img标签src属性没有这这种限制,利用这个“漏洞”就可以很好的解决跨域请求。JSONP就是利用了script标签无同源限制的特点来实现的,当向第三方站点请求时,我们可以将此请求放在

<script src="http://www.b.com/request?para1=1"></script>

JSONP的优缺点
优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

JSONP前端请求实现
script标签设置src属性为请求的地址,并判断回调函数作为参数
服务端构建JS脚本,传递返回给客户端的数据
客户端在回调函数中解析服务器生成的数据

2. postMessage 跨域

代码写完后看自己页面的路径地址,有没有实现跨域,第三个也一样
index.html页面

<body>
    <iframe src="http://127.0.0.1:8080/message.html" id="frm"></iframe>
    <input type="button" value="ok" onclick="run()">
    <!-- 绑定点击事件,模拟传输数据 -->
    <script>
        function run(){
            let frm =document.getElementById("frm");
            //contentWindow.postMessage,这个属性可以传递数据
            frm.contentWindow.postMessage({name:"张三李四"},"http://127.0.0.1:8080")//name:"张三李四",第一个参是数据,第二个是跨域的地址
        }
    </script>
</body>

message.html页面

<body>
    <script>
        //接收index.html的数据
     window.addEventListener("message",function(e){
         console.log(e.data); 
     })    
    </script>
</body>

server.js页面

let express= require("express");
let app = express();
// 解析静态资源文件的;
app.use(express.static(__dirname));
app.listen(8080,function(){//8080启动的端口号
    console.log("启动成功");
})

3.CROS跨域

index.html页面

<body>
    <script src="../node_modules/axios/dist/axios.min.js"></script>
    <script>
        // 从5501向8080发送请求,被阻断了,跨域;
        axios.get("http://127.0.0.1:8080/getData").then(function(data){
            console.log(data.data); 
        })
    </script>
</body>

server.js页面

let  express = require("express");
let app = express();
// 利用cros解决跨域
app.use(function(req,res,next){
    // http://127.0.0.1:5501:设置允许的请求地址, * : 代表所有的路径
    // Origin 字段,表示本次请求来自哪个源(协议 + 域名 + 端口),服务端会获取到这个值,然后判断是否同意这次请求并返回。
    // res.header 设置响应头
    res.header("Access-Control-Allow-Origin","http://127.0.0.1:5501");
    // 设置允许的跨域请求方式
    res.header("Access-Control-Allow-Methods","GET,POST")
    next();
});
// 路由
app.get("/getData",function(req,res){///getData这个路由在a.html用到了
    res.send("你很帅");
});
//想启动项目首先要下载express,有这个才能运行server
//在安装一个生产依赖axios
app.listen(8080);//listen,监听的端口

4.proxy代理

  1. 如果你的前端应用和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下将 API 请求代理到 API 服务器。这个问题可以通过 vue.config.js 中的 devServer.proxy 选项来配置。
  2. proxy代理;实现跨域;前端项目部署在本地的8080端口,向知乎域名请求数据,是跨域,需要配置proxy;在前端看似访问8080,实际在node环境下会将访问的地址代理到知乎的服务器上;
    proxy代理是基于node中间层实现的,node没有跨域的说法,可以访问任何服务器上的数据源
module.exports = {
  lintOnSave: false,
  publicPath:"./",//./是公共路径,基础路径,跟src是同级的在这可以实现跨域devServer
  devServer:{
    // proxy代理;实现跨域;前端项目部署在本地的8080端口,向知乎域名请求数据,是跨域,需要配置proxy;在前端看似访问8080,实际在node环境下会将访问的地址代理到知乎的服务器上;
    proxy:'https://www.zhihu.com/api'
  }
}


// 当期这个文件是vue/cli的生成的项目的配置文件;因为这个项目没有webpack.config.js文件,你所想要的所有的配置都在这个文件中配置就可以了
module.exports = {
    publicPath: './',//这个值也可以被设置为空字符串 ('') 或是相对路径 ('./'),这样所有的资源都会被链接为相对路径,这样打出来的包可以被部署在任意路径,
    lintOnSave:false, // 如果是false,那么eslint代码校验就不在抛出警告
    devServer:{ // 配置代理
        proxy: 'http://localhost:3000' // 后台项目的跑的端口号
    },
    // 会将这个对象和内置的配置文件进行合并
    // configureWebpack:{
    //     modules:{
    //         rules:[
    //             {
    //                 test:/\.(png|jpg|gif|)$/,
    //                 use:['url-loader']
    //             }
    //         ]
    //     }
    // }
}

5.CROS跨域

这个一般都是后台来做,看一下模拟接口下的CROS跨域。
关于跨域的问题_第1张图片
关于跨域的问题_第2张图片

具体可以参照VUE CLI官网:https://cli.vuejs.org/zh/config/#devserver-proxy
有空会给每一个加上详细讲解

你可能感兴趣的:(Node.js,node.js)