什么是跨域?

要解释跨域,就要先说明下什么是域?域的英文名是Domain,百度百科给的定义是:

域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)

众所周知,网址还有个名字叫做域名。当我们去访问这个域名时,实际上在做的事情是与这个域名下的一个或多个服务器建立起链接,去获取想要的信息。在这个域名下的一个或多个服务器就共同组成了一个域,就类似于国家一样,一个或多个省份组成了一个国家。

当一个域去访问获取另一个域的信息的时候就是跨域了,举个例子就是就是当你打开baidu.com的时候,在这个域名下想获取taobao.com下的某个数据,那么这就是一个跨域请求。跨域访问是有限制,例如ajax就是不支持跨域请求的。就好比你要出国,你需要护照需要签证,不然别的国家不会让你入境。跨域问题也是一样,如果你的请求不合法是不允许你跨域访问的。

ajax为什么不支持跨域?

这是个蛮有意思的问题,可以先想一下为什么去别的国家需要签证需要护照的这么麻烦。有一个很重要的原因就是国家的安全,如果不加以筛选和限制,来了些不好的人,那么这个国家也不安全,访问这个这个国家的人也不安全。

不允许ajax访问也是一个道理,在web安全中有一个很重要的安全策略就是同源策略,同源这个源也可以理解成域,这里翻译下Understanding the Web-Same Origin Policy, Restrictions, Purpose, and Workarounds这篇文章的部分段落,简单介绍下什么是同源策略(若不准确建议看下原文)

DOM 同源策略:

不同源的页面下,是不允许对页面的DOM进行读写操作的。这可以阻止大量的对用户信息窃取的攻击,一个简单的例子如下:

  1. MaliciousSite.com这个页面下有个链接指向mybank.com

  2. 用户点击这个链接的时候,MaliciousSite.com就会通过window.open这个JavaScript脚本在一个新窗口里打开mybank.com这个网页

  3. 通过这个打开mybank.com的窗口,MaliciousSite.com能够读写mybank.com网页里的信息。

XmlHttpRequest(ajax)同源策略

XmlHttpRequest的同源策略是,不允许通过JavaScript的xmlhttp想不同域名的网站建立起http的requests请求,所以“正常”的ajax请求是不能跨域的。 与DOM的同源策略相比,XmlHttpRequest同源策略是为了阻止一种不同的攻击方式,这是十分重要的。XmlHttpRequest是为了防止Cross Site Request Forgery(CSRF)攻击。当HTTP请求建立的时候,浏览器将会发送属于这个请求域名的cookies。实际上,当你访问一个网站时,这个网站会有一个授权的cookie来让你访问。基于此,如果没有XmlHttpRequest同源策略,那么一个CSRF攻击就可能会实现,例子如下:

  1. 用户通过浏览器访问了一个恶意网站MaliciousSite.com

  2. MaliciousSite.com在不让用户知道的情况下悄悄的访问另一个网站MyBank.com

  3. MyBank.com通过web服务将信息传递给使用者

  4. MaliciousSite.com获取了MyBank.com传给用户的信息。MyBank.com之所以会响应请求,是因为用户是被授权的,并且通过ajax发送了这个授权的cookie。

翻译的肯定不如原文清楚,这也是为什么有时候看英文的能看懂看翻译的就看不懂了,如果还是不明白,建议看下原文吧,我的英文翻译水平有限见谅啦。

jsonp跨域原理及过程

原理

跨域不可避免,既然ajax无法跨域,那肯定要通过别的途径了。想一下写页面的时候,有时候我们引入的css或者js文件并不是本地服务器上的,可能就是某个cdn上的。所以突破口就这里,如果标签里src放的不是资源文件,放的是个请求,岂不是就可以实现跨域了?要知道url也是可放请求的,当然这还需要后端的配合。

过程

jsonp的实现过程大体分为3个阶段。 
1. 生成get请求的url。为什么是get不是post,因为src属性发起的HTTP请求就是get方式,至于get和post有什么区别,这个自己在补补课吧,就不赘述了。 
2. 创建script标签,将src的属性设为请求的url,并插入到页面中。这里一定要放入到页面中才可,因为不放入到页面中的话,浏览器不会渲染,因此也不会去执行。 
3. 获取跨域请求获得的信息。这里要注意下,有许多跨域请求时,怎么知道信息返回给谁呢?所以又有个识别码在url里的。

附上个简单的伪代码

//获取url
function getURL(){
//dom操作
var url = "http://domain.com/somejson?name=test?id=1";
return url;
}
//建立标签
function createScript(src){
var Scrip=document.createElement('script');
Scrip.src=src;
document.body.appendChild(Scrip);
}
function readJson() {
//获取标签里的信息
console.log(json);//Object { number="1111"}
}

最后注意下,使用jsonp有个问题就是不知道这个请求是否成功还是失败,因为没有状态码,因此还需要设置个定时器。

问题

面试的时候考官问了个问题,就是为什么src能跨域,我的推测就是个w3c的标准,但是没有找到相关的信息,所以有谁知道就请告诉我吧,谢谢啦。

更新

前两天面试也是问到个关于jsonp的跨域问题,不过这次把我问蒙了,问的是如果用post进行ajax的跨域请求。当时想了一会,设计了个方法答了下,回来后特意查了查,发现完全说的驴唇不对马嘴啊。。所以专门更新写一下post的ajax跨域请求吧。

AJAX的post跨域

在《JavaScript高级程序设计》的第21.4跨源资源共享中,说到了一个方法叫COR(Cross-Origin Resource Sharing),这里引述下这段解释下

CORS(Cross-Origin Resource Sharing,跨源资源共享)是W3C 的一个工作草案,定义了在必须访问跨源资源时,浏览器与服务器应该如何沟通。CORS 背后的基本思想,就是使用自定义的HTTP 头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。

get已经能跨域了,为什么还要折腾个post呢?因为get对于数据的请求是有大小限制的,而且不安全,用post就能很好的解决,所以post的跨域也是必不可少的。

CORS的请求过程

CORS的请求过程与正常的ajax基本一样,不过增加了一个自定义http头部的交流过程,具体过程如下:

  1. 前端:发送请求时需要一个Origin头部,其中包含请求页面的源信息(协议、域名和端口),以便服务器根据这个头部信息来决定是否给予相应。一个Origin头部的实例:Origin:http://www.baidu.com。这个Origin头部不需要单独设置,请求时自动的就会有。另外注意一点使用CORS时,url路径要写完整的路径,包括协议、域名和端口号等。
  2. 后端:服务器接到这个请求后,如果认为可接受,就在Access-Control-Allow-Origin 头部中回发相同的源信息(如果是公共资源,可以回发”*”)。例如:Access-Control-Allow-Origin: http://www.baidu.com。如果没有这个头部,或者有但是源信息不匹配,那么就会驳回。另外请求和响应都没有cookie信息。

兼容性

兼容性这块还是爱搞特殊的IE啦。IE8以下都不支持,另外在IE8下要使用CORS需要引入XDR类型,也就是创建一个XDomainRequest示例,而不是XMLHttpRequest示例。最后附以下浏览器兼容性的表吧。 

上图来自于Can I use

跨域及jsonp的更多相关文章

  1. jQuery(三) javascript跨域问题(JSONP解决)

    加油~ --WH 一.什么是javascript跨域问题? 域:服务器域名,唯一标识(协议,域名,端口)必须保证一致,说明域相同 跨域:在一个服务器上,去访问另一个服务器上,并且得到另一个服务器返回回 ...

  2. 浏览器同源策略,跨域请求jsonp

    浏览器的同源策略 浏览器安全的基石是"同源政策"(same-origin policy) 含义: 1995年,同源政策由 Netscape 公司引入浏览器.目前,所有浏览器都实行这 ...

  3. 跨域Ajax -- jsonp和cors

    跨域Ajax - jsonp - cors 参考博客: http://www.cnblogs.com/wupeiqi/articles/5703697.html http://www.cnblogs. ...

  4. jquery跨域解决方案JSONP

    1.在互联网中我们的计算机是通过IP来定位的,但是IP比较难记忆,因此通过domain name(域名)来取代IP 2.什么是跨域? (1)默认浏览器为了安全问题,禁止了xmlhttprequest跨 ...

  5. Ajax跨域:Jsonp实例--百度搜索框下拉提示

    Ajax跨域:Jsonp实例--百度搜索框下拉提示 一.总结 一句话总结:a.找好接口:b.用script标签的src引入文件(json数据):c.定义及实现上一步引入文件中的函数 1.如何找到一个网 ...

  6. JS跨域:jsonp、跨域资源共享、iframe+window.name

    JS跨域:jsonp.跨域资源共享.iframe+window.name :https://www.cnblogs.com/doudoublog/p/8652213.html JS中的跨域 请求跨域有 ...

  7. 【记录】ajax跨域问题jsonp正确的使用方式

    最近遇到ajax请求跨域问题,解决方案用jsonp,现记录如下: //跨域请求jsonp封装 function doJsonPostCallBack(type, url, data,async, ca ...

  8. cors跨域和jsonp劫持漏洞 和 同源策略和跨域请求解决方案

    cors跨域和jsonp劫持漏洞: https://www.toutiao.com/a6759064986984645127/ 同源策略和跨域请求解决方案:https://www.jianshu.co ...

  9. 前端跨域解决方案: JSONP的通俗解说和实践

     对于前端开发者而言,跨域是一个绕不开的话题.只有真正明白了各种方案的工作机制,才能针对性地进行跨域方案选型.本文将以探索者的视角,试图用最通俗的语言对一种"鼎鼎大名"的跨域解决方 ...

  10. 跨域的jsonP

    1.出现原因:因为web中的同源策略(域名,协议,端口号)限制了跨域访问.   2.区别于json (个人理解)json是数据交换格式,jsonp是数据通信中的交互方式   3.jsonp的get与p ...

随机推荐

  1. mybatis-传多个参数

    第一种方案:下标传参 DAO层的函数方法 Public User selectUser(String name, String area); 对应的Mapper.xml <select id=& ...

  2. mysql语句实现年龄分布

    select nnd as '年龄段',count(*) as '人数' from( select case when age>= and age<= then '1-10' when a ...

  3. 从设计稿到实现React应用(分类数据处理)

    1. 确定设计稿和数据 设计稿: 数据: [ {category: "Sporting Goods", price: "$49.99", stocked: tr ...

  4. 067_查看 KVM 虚拟机中的网卡信息(不需要进入启动或进入虚拟机)

    #!/bin/bash #该脚本使用 guestmount 工具,可以将虚拟机的磁盘系统挂载到真实机文件系统中#Centos7.2 中安装 libguestfs-tools-c 可以获得 guestm ...

  5. 判断声明出来的list为空的时候,list!=null

    判断声明出来的list为空的时候,listjcxm!=null&&listjcxm.size()==0: 有时候list不为null但是size为0 map也是类似

  6. 学习笔记:Linux下共享内存的方式实现进程间的相互通信

    一.常用函数 函数系列头文件 #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ft ...

  7. linux删除目录下指定后缀的文件

    这几天在Colab上使用ImageAI训练模型时每次都会保存精确度有所提升的模型,这些模型可以算是中间产物,不太重要.为了避免混淆,运行完通过以下命令删除. find . -name "*. ...

  8. docker-compose 布署应用nginx中的create-react-app应用获取环境变量

    文章来源:https://www.freecodecamp.org/news/how-to-implement-runtime-environment-variables-with-create-re ...

  9. Windows安装Centos7双系统后Windows启动项消失

    原文: https://www.cnblogs.com/xinglichao/p/9999049.html https://blog.csdn.net/yingzinanfei/article/det ...

  10. 基于python的人脸识别(检测人脸、眼睛、嘴巴、鼻子......)

    本文链接:https://blog.csdn.net/James_Ray_Murphy/article/details/79209172 import numpy as np import cv2 # ...