文章目录

  • 1.同源策略于跨域
    • 1.1 同源策略
    • 1.2 跨域
    • 1.3 为什么要设定跨域这个概念
  • 2.解决跨域的方案
    • 2.1 jsonp
    • 2.2 CORS
    • 2.3 CORS和jsonp的比较

1.同源策略于跨域

1.1 同源策略

首先我认为想要了解跨域前必须先要知道浏览器的同源策略。

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源指的是协议、域名、端口相同。

同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准,其目的是防止某个文档或脚本从多个不同 源装载。

其实在13年之前,在还没有提出前后端分离时。大多项目都是同源的,因为项目的前端页面不是复杂,通常直接将前端页面放在服务器上,直接进行服务器渲染。用户直接请求到html页面。

但是随着时间的推移前端界面变得越来越重要。如果将所以的前端界面放在服务器进行服务器端渲染,这无疑增加了服务器的压力。这时候就提出了前后端分离。所谓前后端分离就是前端有自己的web服务器,后端只提供数据,web服务器在另一边进行请求。这样就产生了一个问题。跨域

1.2 跨域

经过上面的描述,或许你已经基本清楚了跨域时怎么回事。

首先跨域是浏览器为了防止出现安全问题的一种机制

我们来看一下跨域的具体表现:

  1. 协议不同,如http, https
  2. 端口不同
  3. 主域相同,子域不同;
  4. 主域不同;
  5. IP地址和域名之间也算是跨域,浏览器不会自动做IP域名的映射

来看一个典型的跨域的例子:
现在我的服务器端口号是8000,web服务器的端口是5050。在web页面直接进行Ajax请求。会出现以下的错误内容:

读一下报错信息大概的意思就是http请求无法将端口为8000的服务器的数据读到5500端口的web界面。

1.3 为什么要设定跨域这个概念

上面也说到跨域是浏览器设定的一种机制。

细心的同学可能已经出现跨域情况时浏览器给我们的状态还是200。这就足以说明跨域是浏览器的机制,只是数据被拦截。请求时成功的。

那么到底到底为什么会有跨域呢?看一下几个场景:

1.用户登录了自己的aaa页面 http://aaa.com,http://aaa.com向用户的cookie中添加用户标识。

2.用户浏览了恶意页面 http://bbb.com。执行了页面中的恶意AJAX请求代码。

3.http://bbb.com向http://aaa.com发起AJAX HTTP请求,请求会默认把http://aaa.com对应cookie也同时发送 过去。

4.aaa页面从发送的cookie中提取用户标识,验证用户无误,response中返回请求数据。此时数据就泄露了。

5.而且由于Ajax在后台执行,用户无法感知这一过程。

2.解决跨域的方案

其实解决跨域的方式一共有7种,我这里一一列举出来

  1. jsonp
  2. cors
  3. 基于proxy(webpack-dev-server实现)
  4. postmessage
  5. socket.io
  6. iframe解决
  7. nginx反向代理

我们前端经常使用的其实前三种,jsonp其实相对于后两者有劣势。在实际开发种最最常用的还是cors和proxy。

但是本文介绍以下前两种(面试点)

2.1 jsonp

jsonp的原理其实有一点套娃的意思。使用回调函数"骗过"浏览器。

我们可以通过使用html的script标记来进行跨域请求,并在相应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。这种跨域的通讯方式成为JSONP。

因为script的src属性本身就是一个不会产生跨域的get请求。所以我们可以将回调函数写在URL中,然后再服务端处理传值,再再客户端设置一个全局的函数来执行回调函数。

下面我们来实现一个简单的jsonp案例:

客户端server.js:

const http = require('http');
const urly = require('url');
var obj={name:'jam',age:'12'
}
http.createServer((req,res) => {var parmer=urly.parse(req.url,true)console.log(parmer);//判断是否跨域(是否有parmer.query.callback这个值,如果有,拼接成带有参数的函数,传给客户端)if (parmer.query.callback) {var str=parmer.query.callback+'('+JSON.stringify(obj)+')'res.write(str);}else{res.write(JSON.stringify(obj));}res.end();
}).listen(8000,function () { console.log('服务器开启');});

客户端client.js:

<!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>
<script>//要执行的回调韩素华function hello(data) {console.log(data);}</script>//使用script标签进行get请求,后接要传给服务端的回调函数
<script src="http://127.0.0.1:8000/?callback=hello"></script>
<body>
</body>
</html>

我们经常使用的jQuery中进行Ajax请求时设置的dataType属性为jsonp其实也是使用的这个原理。

不足之处:

  1. 只能进行get请求,标签限定
  2. 需要定义全局函数

2.2 CORS

跨域资源共享

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。 CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。 整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信 没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附 加的请求,但用户不会有感觉。 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

这种方式也是我们经常使用的,通常在后端进行设定CORS相关属性。前端直接请求即可。

下面我贴出在express框架中的使用方法。

手动:

app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Authorization,X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method' )
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PATCH, PUT, DELETE')
res.header('Allow', 'GET, POST, PATCH, OPTIONS, PUT, DELETE')
next();
});

使用cors包(封装):

npm install cors --save-devconst cors = require('cors');
app.use(cors());

我们这里需要注意的是在设置Origin字段时可以有两种情况:*和一个域名

在使用*(接受所有域名)的时候浏览器为了安全考虑是不会发送Cookie值的,使用一个域名的时候是可以的。但是在实际开发中我们通常只需要使用一个域名就可以完成业务了。

2.3 CORS和jsonp的比较

  1. jsonp可以支持老式浏览器,但是处理get请求。
  2. CORS支持几乎所有方式,当时不支持IE10一下浏览器
  3. 综合下来CORS是要比jsonp强大的。

好了关于后面的方式proxy也是比较常见的,剩下的就用的不太多了。

关于proxy后面再去整理

跨域解决方式——JSONP,CORS相关推荐

  1. 跨域解决方法——jsonp原理

    跨域解决方法--jsonp原理 一个域名地址的组成: 当协议.子域名.主域名.端口号任意一个不相同时,都算作不同域,不同域之间相互请求资源,就算做"跨域".由于浏览器同源策略的限制 ...

  2. js跨域请求方式 ---- JSONP原理解析

    这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的X ...

  3. Nginx跨域解决配置示例

    简介 在日常学习和工作开发中,需要请求两个不同配置的请求经常存在,本文介绍如果还使用Nginx配置解决其跨域问题 相关理论 首先需要了解什么是跨域,下面的两个文章说的很好,请仔细阅读后,然后自己去动手 ...

  4. JavaScript跨域解决方法大全

    跨域的定义:JavaScript出于安全性考虑,同源策略机制对跨域访问做了限制.域仅仅是通过"URL的首部"字符串进行识别,"URL的首部"指window.lo ...

  5. 跨域问题及解决方式(CORS)

    跨域问题及解决方式(CORS) 1. 背景 2. 什么是跨域? 3. 非同源限制 4. 跨域解决方案 4.1 cors 4.2 nginx 4.2 其他方式 1. 背景 项目中在用图片验证码,项目重启 ...

  6. 深入跨域问题(2) - 利用 CORS 解决跨域

    阅读目录: 深入跨域问题(1) - 初识 CORS 跨域资源共享: 深入跨域问题(2) - 利用 CORS 解决跨域(本篇) 深入跨域问题(3) - 利用 JSONP 解决跨域 深入跨域问题(4) - ...

  7. jquery、javascript实现(get、post两种方式)跨域解决方法

     jquery.javascript实现(get.post两种方式)跨域解决方法 一.实现get方式跨域请求数据 浏览器端 <script> $(document).ready(fun ...

  8. PHP的介绍及应用,ajax的介绍及应用,跨域问题及jsonp解决方法

    PHP(服务器编程语言) 服务器由环境(Apache),数据库(mysql),代码(HTML+css +js,php)组成. PHP必须在服务器的环境下执行 php与js最大的区别就是工作环境,PHP ...

  9. CORS了解与VUE跨域解决

    1.CORS了解 CORS通信得关键地方就是服务器,只要服务器实现了CORS接口,就可以实现跨域通信 浏览器将CORS请求分为两大类:简单请求.非简单请求 简单请求 基本介绍 同时满足以下条件就是简单 ...

最新文章

  1. 几句话描述简单算法——排序与搜索
  2. CentOS release 6.2 共享文件夹
  3. Winform中实现简单的登录成功后跳转到主页面的逻辑
  4. 【机器学习】集成模型方法
  5. SQL基础操作_4_表的插入、更新、删除、合并操作
  6. python爬虫用多线程还是多进程_python爬虫之多线程、多进程爬虫
  7. mysql解压版安装配置
  8. serve : 无法加载文件 C:\Users\wb\AppData\Roaming\npm\serve.ps1
  9. MyBatis调用存储过程,含有返回结果集、return参数和output参数
  10. 19【推荐系统5】NeuralCF
  11. 浏览器是否支持Html5
  12. 编程之美 1.4买书问题常数时间空间解法
  13. VS真难用:好好的编译工程,换个机器完全不能编译;换高版本还是不能编译
  14. 机械设计基础课程设计【1】
  15. 城市生态规划关键技术方法之六:情景分析方法
  16. 一文搞定计算机网络面试题
  17. 10分钟轻松定制网站日志分析大盘
  18. 【细胞分割】基于阙值+边缘+形态学+种子点图像分割matlab源码含 GUI
  19. 吉首大学2019年程序设计竞赛(重现赛)B——干物妹小埋(树状数组+二分)
  20. Vue环境配置时报npm WARN deprecated bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features

热门文章

  1. 验证与github是否连接成功.
  2. Qt-qss之QSlider滑动条美化
  3. vue2 django前后端分离(一.环境搭建)
  4. 计算机本科生需要具备的素养
  5. 全球致盲眼疾排名第一能轻松治疗,第二名却很难处理...
  6. 外贸怎么找客户之土耳其进出口海关数据
  7. 概率论与数理统计---随机事件及其概率(一)
  8. HTTP协议-教程(一)
  9. 当《出师表》翻译成白话文
  10. WiderFace数据集用于训练人脸检测模型