㈠ web前端跨域的一些解决方案
没有归纳之前对跨域的一些说法是模糊的,什么jsonp啊,跨域原理啊,心里只有一个大概的说法,知道这个东西,然后用的时候直接网络Ctrl+C,后来闲下来决定整理一波这些知识点,需知其所以然。
那么,其实这是浏览器对我们的一种保护机制,把坏人挡在门外。那么,问题来了,我们怎么确定门外的人到底是好人还是坏人呢?浏览器关上了坏人的一扇门,留给了我们好人一扇窗。
JSONP跟JSON没有关系..就好像JavaScript和Java一样
浏览器对script、img(这些标签的请求方式都是 GET ,所以jsonp不支持 POST )这种标签没有限制,我们就可以这样干
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
服务器端对于CORS的支持,主要就是通过设置 Access-Control-Allow-Origin 来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。 更多有关跨域资源共享 CORS 的知识
浏览器中可以查看对应的响应头,举个例子,如下
服务端允许CORS,服务端需要针对接口设置的一系列响应头 (Response Headers)
1.简单请求
目前大多数情况都采用这种方式。简单请求只需要设置 Access-Control-Allow-Origin 即可。满足以下两个条件,就属于简单请求。
2.非简单请求
非简单请求会发出一次预检测请求,返回码是204,预检测通过才会真正发出请求,这才返回200。来看栗子:
非简单请求需要根据不同情况配置不同的响应头,一系列响应头配置项见上方
这个说法相信不陌生,我们依然使用前端域名请求,然后有一个 中介商---代理 把这个请求转发到真正的后端域名上,那也就不存在跨域问题了。
比较普遍的Nginx,简单的配置一下就可以了。了解更多的配置信息: nginx详解
然后前端这边的请求地址是 http://localhost:9099/api/xxx ,然后Nginx监听到地址是 localhost:9099/api 的请求,就帮我们转发到真正的服务端地址 http://.com
CORS与JSONP的使用目的相同,但是比JSONP更强大。JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及在服务端同意jsonp方式时,可以向不支持CORS的网站请求数据。Nginx可以说是最方便的,不过需要部署Nginx才行,需要对服务器有一定的理解,不太适合刚入门的同学,当然也可以请后台同学帮忙部署。
window.postMessage(data,origin) 是 HTML5 的一个接口,专注实现不同窗口不同页面的跨域通讯。
现在是这么一个情况,由于同源策略的限制下, a.html 不能操作iframe( b.html )里面的dom,那么使用postMessage就可以解决这一情况
然后 b.html 页面通过message事件监听并接受消息:
这种方式只适合主域名相同,但子域名不同的iframe跨域。
比如主域名是 http://.com/:8888 ,子域名是 http://child..com/:8888 ,这种情况下给两个页面设置相同的document.domain即document.domain = .com 就可以访问各自的window对象了。
前端跨域整理
不要再问我跨域的问题了
㈡ 如何解决前端跨域问题
可以使用服务器代理或者在后端设置允许跨域。
现在的项目一般是在后端设置允许跨域,前端在带有允许跨域的情况下,可以像没有跨域一样正常访问。
如果前端单独发布到服务器,也可以在服务器是设置代理,使用代理转发请求。
㈢ 前端跨域的几种解决方案
1.Cookie、LocalStorage和IndexDB无法读取
2.DOM和JS对象无法获取
3.Ajax请求不能发送
1.简单请求
2.非简单请求
1.请求方法是以下三种方法之一.
2.HTTP请求头必须是下面几种字段
对于简单请求就是浏览器直接发出CORS,具体来说就是请求头添加Origin字段
如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息响应字段
1.Access-Control-Allow-Origin:必选
2.Access-Control-Allow-Credentials:可选
3.Access-Control-Expose-Headers
"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。
除了Origin字段,“预检”请求的头信息包括两个特殊字段。
1.Access-Control-Request-Method
2.Access-Control-Request-Headers
服务器收到“预检”请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。
㈣ 前端跨域如何解决
什么是跨域?
跨域是通俗的说是从一个域名去请求另一个域名的资源。比如从 www..com 页面去请求 www.taobao.com 的资源。
跨域严格一点来说:两个域名只要协议,域名,端口中只要有一个不同,就被成为跨域
浏览器为什么要限制跨域?
只有同域才可以拿到存在cookie中的信息,防止坏人随意拿到我们的信息去做坏事
在团队的配置中,我们为了减少前端对后端的依赖,提高开发效率,使前后端职责更清晰等等因素,我们不得不面对跨域的问题,那我们该怎么解决呢?
1、 JSONP
原理:浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行,所以通过动态插入script标签即可达到跨域的请求
特点:数据为json格式
缺点:不能post
2、 CORS
原理 : cors(Cross-Origin Resource Sharing)是 W3C CORS 工作草案 ,它定义了在跨域访问资源时浏览器和服务器之间如何通信。CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否
特点 :是 JSONP 模式的现代版。支持更多的请求方式,XMLHttpRequest
缺点:需后端配合修改,现代浏览器支持cors,老浏览器依旧要用JSONP
3、 PROXY
原理:proxy代理用于将请求拦截,然后通过服务器来发送请求,然后再将请求的结果传递给前端
node通常用 node-http-proxy 即可
proxy太通用了,weblack-dev-server里已集成,使用时直接配置即可 webpack-dev-server proxy代理
㈤ 前端解决跨域都有哪些方法
什么是跨域?
浏览器发送的请求地址(URL)与所在页面的地址 不同(端口/协议/域名 其一不同)。简言之,浏览器发出的请求url,与其所在页面的url不一样。此时,同源策略会让浏览器拒收 服务器响应回来的数据,报错信息如下:
最常用的四种跨域解决方案
1.cors
cors跨域资源共享允许是在服务端"Access-Control-Allow-Origin"字段设置的,当将cors设置为允许某个地址访问时,该地址就可以跨域访问这个服务器地址。当cors设置为"*"时即允许所有地址访问时,则表示所有地址都可以跨域访问这个服务器地址的资源。
2、 通过jsonp跨域
Jsonp是Json的一种“使用模式”,他就可以解决浏览器遇到的跨域问题,我们可以动态创建script,再请求一个带参网址实现跨域通信。用Jsonp请求得到的是JavaScript,相当于直接用JavaScript解析。
3、postMessage跨域
在h5中新增了postMessage方法,postMessage可以实现跨文档消息传输,我们可以通过Windows的message事件来监听发送跨文档消息传输内容。
4、proxy(代理)
原理:因为同源策略只是针对浏览器的安全策略,但是服务端并不受同源策略的限制,也就不存在跨域的问题。
㈥ 跨域以及解决跨域的几种方式
跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能 同源 使用的限制。
同源策略 是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议 + 域名 + 端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
常见的跨域场景:
对于简单请求,浏览器会直接发出CORS请求,具体的就是在头信息中,增加一个 Origin 字段。
非简单请求是那种对服务器有特殊要求的请求,譬如 put delete 方法,或者 Content-Type 字段类型是 application/json 的,非简单请求在正式通信前,会增加一次请求,称为预检请求,也就是 options 方法。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求,否则就报错。
与简单请求不同的是, option 请求多了2个字段:
Access-Control-Request-Method :必须字段,用来列出浏览器的CORS请求会用到哪些HTTP方法。
Access-Control-Request-Headers :该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段。
服务器收到"预检"请求以后,检查了 Origin 、 Access-Control-Request-Method 和 Access-Control-Request-Headers 字段以后,确认允许跨源请求,就可以做出回应。
表明服务器支持的所有跨域请求的方法。
表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。
表示是否允许发送认证信息(Cookie)。
指定本次预检请求的有效期,单位为秒,允许缓存。在缓存期间,不用发出另一条预检请求。
㈦ 前端的跨域问题理解
前端真的的是乱的一笔。--来自iOS开发者的一声哀鸣
需要把前端看成两部分,一部分是页面,另一部分是接口(或者加数据资源)。前端页面中调接口是有限制的,同源策略(SOP)要求我们调用的接口必须和页面在同一域名下,说是为了保证数据的安全。所谓同源:协议+域名+端口
但实际情况是,在前后端分离的大趋势下,好多页面和接口的服务器分布在不同的域名下。比如在开发时,前端页面分为本地环境、测试环境、仿真环境、正式环境,而接口也分为测试环境、仿真环境、正式环境,当然也可以有本地环境。他们在不同的域名下或IP下或者端口下,是不同源的。或者平时我们也能遇到需要调用不同的服务器数据资源。显然,同源策略保障了部分安全的同时,给开发造成了很多的麻烦。
所以,跨域问题是每个前端绕不过去的坎儿。
解决办法有两个方向,一个是前端解决,一个是服务端接口解除限制。
前端解决就是通过jsonp、jquery ajax、axios配置代理等。还有个简单的,比如Mac用户,可以使用Charles工具设置代理,临时使用。
服务端解决可以通过nginx反向代理设置允许跨域请求的域名、或者设置Access-Control-Allow-Origin,允许跨域资源共享等。
具体解决方案可参考 https://segmentfault.com/a/1190000011145364
反观iOS,轮廓简直不要太清晰,大部分时候只用专注于开发,没有各种乱七八糟的事情。
㈧ 后端解决前端跨域请求问题
场景:前后端分离,页面和后端项目部署在不同服务器,出现请求跨域问题。
原因:CORS:跨来源资源共享(CORS)是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比JSONP要来的好,JSONP对于 RESTful 的 API 来说,发送 POST/PUT/DELET 请求将成为问题,不利于接口的统一。但另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。不过现代的浏览器(IE10以上)基本都支持 CORS。
预检请求(option):在 CORS 中,可以使用 OPTIONS 方法发起一个预检请求(一般都是浏览检测到请求跨域时,会自动发起),以检测实际请求是否可以被服务器所接受。预检请求报文中的 Access-Control-Request-Method 首部字段告知服务器实际请求所使用的 HTTP 方法;Access-Control-Request-Headers 首部字段告知服务器实际请求所携带的自定义首部字段。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。
解决方案:
1、创建一个过滤器,过滤options请求。
package com.biz.eisp.sci.util;
import org.apache.commons.httpclient.HttpStatus;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 解决跨域问题
*
*/
public class CorsFilterimplements Filter {//filter 接口的自定义实现
public void init(FilterConfig filterConfig)throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
response.setHeader("Access-Control-Allow-Origin", "*");
if ("OPTIONS".equals(request.getMethod())){//这里通过判断请求的方法,判断此次是否是预检请求,如果是,立即返回一个204状态吗,标示,允许跨域;预检后,正式请求,这个方法参数就是我们设置的post了
response.setStatus(HttpStatus.SC_NO_CONTENT); //HttpStatus.SC_NO_CONTENT = 204
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");//当判定为预检请求后,设定允许请求的方法
response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with"); //当判定为预检请求后,设定允许请求的头部类型
response.addHeader("Access-Control-Max-Age", "1"); // 预检有效保持时间
}
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
2、修改web.xml文件
<filter>
<filter-name>cors</filter-name>
<filter-class>com.biz.eisp.sci.util.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/* </url-pattern>
</filter-mapping>
3、spring-mvc.xml添加HttpRequestHandlerAdapter http请求处理器适配器。
HttpRequestHandlerAdapter作为HTTP请求处理器适配器仅仅支持对HTTP请求处理器的适配。它简单的将HTTP请求对象和响应对象传递给HTTP请求处理器的实现,它并不需要返回值。它主要应用在基于HTTP的远程调用的实现上。
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
㈨ 前端跨域解决 (vscode live server proxy 代理)
这个显然是处理前端跨域最优的方法了,在此记录下来方便以后使用,附送scss 转 css
使用 vscode IDE作为编写工具
1.搜索并加载 vscode 插件 live server
2.要文件根目录创建 ".vscode" 目录
3.在 .vscode 目录下创建settings.json
4.proxUri 为代理的目标地址
5.baseUri 识别代理的符号 (如下例中 baseUri: '/api', 则以"/api"开头的网络请求都将被识别为需要代理转发的地址,并把 ‘/api’重写为空"")
1.ajax请求会受到浏览器同源策略的限制(同源 = 域名 + 端口 都一致)
2.ajax请求默认携带 同源下的所有cookie, 如果不做限制 a 去请求 b 的时候就等于把a所有的cookie 都告诉b。
3.同源下: 张三的网站只能访问张三的内容如鞋子衣服吃饭等等,如果想访问李四的,浏览器就不让你干了。如果充许这么干的话,张三的cookie隐私将直接暴露给李四,李四有可能干一些不怀好意的事情。
4.跨域情况:张三把钱都放在李四那里,现在张三想去李四那边取钱,这时候就需要跨域了。
5.跨域怎么解决呢?接下来把解决问题的思路简单描绘一下。
5.1:李四告诉全世界说我对钱不感兴趣,只要我有,你们所有人都随便来取。因此,当浏览器看到张三要取钱的人是李四这种慈善家,就不再拦着你了。
5.2:李四不是慈善家怎么办?于是张三这个时候就很讨厌浏览器,想了个办法绕过浏览器,然后另外找了个代理去跟李四取钱
5.2.1: 问题是绕过浏览器?怎么绕呢? 于是张三自己建了个服务器,每次要跟李四取钱的时候就欺骗浏览器说我要跟自己的服务器取钱,浏览器这个时候也就不再拦着你了
5.2.2:当张三自己的服务器接收到跟李四取钱任务后,就以proxy代理的身份向李四取钱,取完钱之后再通过浏览器给了张三
5.2.3:vscode 中的live server 插件里面就这个代理向李四取钱的代理服务器功能,本文settings.json 中包含了配置信息
6.当然还有一些很多牛叉的解决跨域的方法。若有兴趣的同学可以一起研究探讨。
㈩ 浏览器跨域及其解决方案
title: 浏览器跨域及其解决方案
author: May
date: 20220428</pre>
什么是跨域跨域的表现解决跨域问题- 浏览器设置(不推荐)- 前端的非正统解决方式- CORS(跨域资源共享)- 配置nginx反向代理
跨域 出于浏览器的同源策略限制, 同源 是指协议、域名、端口都一样, 同源策略(Sameoriginpolicy) 是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
调用页面时接口数据不返回,控制台中会有红色的报错信息中有类似于 CORS policy 关键字。另外,在最新谷歌浏览器中,会有提出类似于loaded over HTTPS此种关键字,均可以考虑为跨域导致。
[图片上传失败...(image-26deed-1651135597111)]
tips: 有的时候后台小伙伴使用postman测试好的接口,前端不可以使用,原因就是postman不是浏览器,不会有同源限制,同理移动设备app开发和小程序开发也不会有这个问题。这个不是前端bug,同源限制也不是一个不好的规则。
虽然跨域不是一个不好的事情,但是对于前后端分离的web开发来说确实需要解决的,大致的解决方案可分为:
直接从根源解决问题,让浏览器安全策略不起作用。这个方法虽然可以解决问题但是不现实。
官方正统解决方案, CORS规范 允许服务器向浏览器返回一些HTTP Headers,浏览器可以基于这些HTTP Headers来决定是否突破SOP的限制。需要后端配合,浏览器需要什么,接口服务给什么。
nginx是一个高性能的HTTP和反向代理web服务器,nginx用来解决跨域问题的原理与 前端非正统解决方式 的 proxy 的思路是一致的。项目请求接口由nginx服务发出,获取到的数据再经由nginx传递给前端项目,这样前端的请求其实都是由nginx处理的,就没有跨域发生了。