博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS中常用的8种跨域方式讲解
阅读量:7119 次
发布时间:2019-06-28

本文共 4063 字,大约阅读时间需要 13 分钟。

1. 什么是跨域

简单的来说就是:

在A域名下向B域名发起了 request。

一个完整的URL应该包含 http(协议)://www.baidu.com(域名):80(端口)/index.html(路由)。

同源策略 就是指的 协议,域名,端口必须保持一致。任何不符合同源策略的请求 request 都属于跨域了。

2.通过jsonp跨域

index.html页面中

        
Document 复制代码

server.js

let express = require('express');let app = express();app.get('/say', function(req, res){    let {wd, cb} = req.query;    res.end(`${cb}('world')`);  //返回 'show('world')'});复制代码

3. 通过CORS跨域

cors.html

        
Document hello cors.html 复制代码
  • cors.html.server.js
let express = require('express');let app = express();app.use(express.static(__dirname));app.listen(3000);复制代码

  • cors.target.js
let express = require('express');let app = express();let whitList = ['http://localhost:3000'];  //用来访问 cors.html的页面app.use(function(req, res, next){    let origin = req.headers.origin;    if(whitList.includes(origin)){        //设置允许哪个源访问我        res.setHeader('Access-Control-Allow-Origin', origin);        //允许携带哪个请求头访问我        res.setHeader('Access-Control-Allow-Headers', 'name');        //允许哪个方法访问我        res.setHeader('Access-Control-Allow-Methods', 'PUT');        //允许携带cookie, 与前端 xhr.withCredentials = true; 相呼应        res.setHeader('Access-Control-Allow-Credentials', true);        //允许的有效期: 第二次发送options方法的时间间隔        res.setHeader('Access-Control-Max-Age', 60); //60s        //允许设置的返回头 与前端 console.log(xhr.getResponseHeader('name'));相呼应        res.setHeader('Access-Control-Expose-Headers', 'name');        if(req.method === 'OPTIONS'){            res.end();  //浏览器在发起put请求前会发送一个options方法,来验证允许访问的各种参数        }    }});app.put('/getData', function(req, res){    console.log(req.headers);    res.setHeader('name','jw');    res.end('hello');});app.use(express.static(__dirname));app.listen(4000)复制代码

从 http://localhost:3000 向 http://localhsot:4000 发送put 请求。

4. 通过postMessage跨域

通过 localhost:3000 访问 a.html

  
Document 复制代码

通过localhost:4000返回 b.html

........复制代码

5. 通过window.name 跨域

默认情况下 window.name 为 "" 有a.html, b.html, c.html. 其中a.html 和 b.html 通过http://localhost:3000访问,c.html通过 http://localhost:4000访问.

a.html

....  a和b是同域的 http://localhost:3000  c是独立的  http://localhost:4000  a获取c的数据  a先引用c c把值放到window.name, 把a引用的地址改到b    

c.html

...  ...复制代码

b.html

  
Document 复制代码

a.html 中的控制台中会打印出 hello a.html

6.通过hash方式跨域

a.html

...  
...复制代码

b.html

... ...复制代码

c.html

......复制代码

7.通过domain方式跨域

a.html

... 
helloa ...复制代码

b.html

...  hellob   ...复制代码

8.通过websocket方式跨域

socket.html

...let socket = new WebSocket('ws://localhost:3000');socket.onopen = function(){    socket.send('hello');}socket.onmessage = function(e){    console.log(e.data); //打印world}...复制代码

server.js

let express = require('express');let app = express();let WebSocket = require('ws');let wss = new WebSocket.Server({port: 3000});wss.on('connection', function(ws){    console.log(data); // 打印 hello    ws.send('world');});复制代码

9.通过nginx方式跨域

a.html

... ...复制代码

nginx.conf

location / {    // 没有配置OPTIONS的话,浏览器如果是自动识别协议(http or https),那么浏览器的自动OPTIONS请求会返回不能跨域    if ($request_method = OPTIONS ) {        add_header Access-Control-Allow-Origin "$http_origin";        add_header Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, DELETE";        add_header Access-Control-Max-Age "3600";        add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";        add_header Access-Control-Allow-Credentials "true";        add_header Content-Length 0;        add_header Content-Type text/plain;        return 200;    }    add_header 'Access-Control-Allow-Origin' '$http_origin';    add_header 'Access-Control-Allow-Credentials' 'true';    add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, OPTIONS';    add_header 'Access-Control-Allow-Headers' 'Content-Type,*';    proxy_pass http://127.0.0.1:8080;    }}复制代码

nginx的方式有些类似cors。

10.小结

平时工作中可能熟知cors 和 jsonp, 这里大概将其原理实现了。以后再遇到面试官问你。就可以淡定的告诉他。然后还可以介绍其他的几种方式。用跨域的方式震慑住他。哈哈哈~~

转载于:https://juejin.im/post/5b19da706fb9a01e4b0623eb

你可能感兴趣的文章
【原】设计稿中字体pt与px之间的转化
查看>>
How to make a not-so-boring speech?
查看>>
Pillow实现图片对比
查看>>
Centos上安装 OpenNebula Management Console
查看>>
【Oracle】 RAC 环境删除oracle 之一
查看>>
android 通过重写ScrollView和Listview完成上下滑动选中不同位置标题的效果
查看>>
[华为机试练习题]34.识别有效的IP地址和掩码并进行分类统计
查看>>
简单选择排序
查看>>
SQL应用与开发:(四)视图的应用
查看>>
dbcp重连失败问题排查记录(timeout设置)
查看>>
Pay attention: Oracle INTEGER is NUMBER(p) not INT4 in PostgreSQL
查看>>
虚拟机linux系统能够上网但是不能ping主机
查看>>
Http 400 --- The request sent by the client was syntactically incorrect
查看>>
关于char**与const char**
查看>>
Linux之同步机制(信号量,自旋锁)
查看>>
nginx内部锁的实现
查看>>
二分查找法
查看>>
硬解码播放器上如何实现截GIF功能?
查看>>
[译] 使用 Kotlin 协程改进应用性能
查看>>
初识URLSeesion
查看>>