博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CORS - 跨域资源共享
阅读量:7143 次
发布时间:2019-06-28

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

hot3.png

一.什么是CORS

    CORS - cross-origin resource sharing,即跨域资源共享。为什么有这个概念,首先介绍同源策略。

    同源策略 - URL由协议、主机名、端口和路径组成,如果两个URL的协议、主机名和端口相同,则表示同源。浏览器的同源策略,限制了来自不同源的文档或脚本,对当前文档读取或设置某些属性。
    简而言之就是浏览器出于网站安全性的考虑,限制不同源之间的资源相互访问的一种策略。
    以下操作具有同源策略的限制:
    (1)Ajax请求不能发送;
    (2)无法获取DOM元素并进行操作;
    (3)无法读取Cookie、LocalStorage 和 IndexDB.

二.CORS的影响

    有过前后端开发的童鞋可能遇到过下面的情况:项目前后端分离的情况下开发的,Ajax请求本地开发的时候OK,为什么和同事联调的时候就出现问题?

    因为CORS限制了不同源的Ajax请求不能发送。

 

三.解决JSON跨域Ajax请求的方案

    1.设置Access-Control-Allow-Origin属性

    在HTTP的请求头中有一个Origin的头信息:表示请求的来源。在服务端的响应头里面对应有一个Access-Control-Allow-Origin的头信息:表示接受的跨域请求来源。假如这两个信息不一致,请求不会被接受。

    记得毕设的时候遇到过这个问题,当时前端请求的时候,后台返回 "No 'Access-Control-Allow-Origin' header is present on the requested resource."
    如果解决这个问题?在服务端加上Access-Control-Allow-Origin-xxx的设置。
    在Git上找到了当时上传的代码片段:

response.setHeader("Access-Control-Allow-Credentials", "true");// 证书可用    response.setHeader("Access-Control-Allow-Methods", "GET,PUT");// 允许哪些HTTP方法可用    response.setHeader("Access-Control-Allow-Origin", "*");// 允许哪些域名可用,这里设置的是通配符,表示所有域名都允许    response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization,Content-Type");// 允许哪些头部信息是可用的    response.setHeader("Access-Control-Max-Age", "30");// 指定本次预检请求的有效期,单位为秒。在有效期间,不用发出另一条预检请求

    这种方式可以防止CSRF(跨站请求伪造)攻击。

    2.JSONP

    维基百科解释: 

JSONP(JSON with Padding)是数据格式JSON的一种'使用模式',可以让网页从别的域名要数据。另一个解决这个问题的新方法是跨域资源共享。由于同源策略,一般来说位于server1.example.com的网页无法与 server2.example.com的服务器沟通,而HTML的 <script>元素是一个例外。利用 <script>元素的这个开放策略,网页可以得到从其他来源动态产生的JSON数据,而这种使用模式就是所谓的 JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。

    "padding" 意为内联,就是将JavaScript加入JSON文档。内联与JSON文档的JavaScript调用一个函数,函数参数是JSON。函数参数提供了一种将数据传递给函数的方式。

    一份JSON文件并不是一个JavaScript程序。为了让浏览器可以在 <script>元素运行,从src里URL 回传的必须是可执行的JavaScript。服务器会在传给浏览器前将JSON数据填充到回调函数中。浏览器得到的回应已不是单纯的数据叙述而是一个脚本。
    该URL回传的是由函数调用包起来的动态生成JSON,这就是JSONP的"填充(padding)"的由来。
    虽然这个填充是浏览器运行背景中定义的某个回调函数,它也可以是变量赋值、if叙述或者是其他JavaScript叙述。JSONP要求(也就是使用JSONP模式的请求)的回应不是JSON也不被当作JSON解析——回传内容可以是任意的表达式,甚至不需要有任何的JSON,不过惯例上填充部分还是会触发函数调用的一小段JavaScript片段,而这个函数调用是作用在JSON格式的数据上的。
    原理:
        在页面中插入一个script标签,创建_callback方法,通过服务器配合执行_callback方法,并传入一些参数。实际上并不是Ajax请求。
        (1)客户端利用script标签可以跨域请求资源的性质,向网页中动态插入script标签,来向服务端请求数据;
        (2)服务端会解析请求的url,拿到回调函数(比如callback=testCallback)参数,之后将数据放入其中返回给客户端;
        (3)jsonp不同于平常的ajax请求,它仅仅支持GET类型的方式。

    简单示例:

    页面:

var url='http://www.baidu.com/"+"?callback=?';    $.ajax({     url:url,     dataType:'jsonp',     processData: false,      type:'get',// JSONP只能使用GET     success:function(data){       // to do     },     error:function(XMLHttpRequest, textStatus, errorThrown) {       // to do     }});

    后台代码:

String callbackName = (String) request.getAttribute("callback");    String json = ESBJSONUtil.objToJsons(results).toString();    String renderStr = callbackName+"("+json+")";// 用参数callbackName在json外面再套一层,就变成了jsonp    response.setContentType("text/html");    response.setCharacterEncoding("utf-8");    response.getWriter().write(renderStr);

    jQuery里面还有一种插件— 。

    3.代理

    可以通过 Nginx 或者 httpd 拦截请求,使之在同一个 domain 下面,代理访问,避免跨域问题。

转载于:https://my.oschina.net/javamaster/blog/2992050

你可能感兴趣的文章
Linux 虚拟网络设备详解之 Bridge 网桥
查看>>
LaTeX的简单使用方法
查看>>
IO流
查看>>
第二十四章:页面导航(四)
查看>>
数字对讲系统开发札记(前端linux c 后端 c#)
查看>>
海外共享公寓品牌Tripalink完成A轮融资,险峰长青领投
查看>>
阿里在使用一种更灵活的软件集成发布模式
查看>>
自己实现一个StringBuffer
查看>>
SpringBoot使用Nacos配置中心
查看>>
星矿科技完成千万元融资,专注明星IP价值商业化
查看>>
SOP 1.2.0 发布,开放平台解决方案项目
查看>>
Element 2.6.3 发布,基于 Vue 2.0 的桌面端组件库
查看>>
丰田研发智能汽车FV2,可利用肢体进行操控
查看>>
基于kubeadm的kubernetes高可用集群部署
查看>>
定位「数字化助手」,腾讯想用服务创新助力产业智慧升级
查看>>
golang之sync.Mutex互斥锁源码分析
查看>>
SAP增强的PA教材内容
查看>>
jQuery系列 第八章 jQuery框架Ajax模块
查看>>
OpenCV中原始图像加载与保存压缩技巧
查看>>
MySQL 8复制性能的增强
查看>>