前后端分离之跨域问题

最近在做的一个项目,原本是通过SpringMVC结合freemarker模板引擎和JSP实现HTML页面和后端的数据交互,现在为了业务需要,要将前后端拆分出来。使用Restful API的形式进行交互。然后刚上路就遇到坑了,在这里记录一下如何填坑,以防不时之需。这里介绍的方法是SpringMVC架构通过CROS协议解决跨域问题。

错误信息

Response to preflight request doesn‘t pass access control check: No ‘Access-Control-Allow-Origin‘ header is present on the requested resource. Origin ‘null‘ is therefore not allowed access. The response had HTTP status code 403.

跨域

Web应用中前端JavaScript访问后端的REST服务默认是不能跨域的,这里的域英文中叫Origin,有时也叫Domain,包含了协议(HTTP/HTTPS),域名和端口号。不能跨域指的是,如果来自http://abc.com:80的JavaScript代码只能访问http://abc.com:80中的资源(HTTP默认端口号为80,注意端口号不同也是不同的域)。现代浏览器默认都会基于安全原因而阻止跨域的ajax请求,这是现代浏览器中必备的功能,但是往往给开发带来不便。

Same Origin Policy(SOP)是浏览器默认的安全模型,为什么需要SOP呢? 因为如果允许JavaScript代码访问非相同域资源的话,那么安全性将变得完全不可控。举个例子,如果另外一个网址中包含的恶意脚本就可以没有任何防备的加载进来,那就就能随意获取或者恶意修改页面元素Cookie信息等。SOP则保证了所有你访问的资源和服务是来自于你自己的服务器,外部的脚本就不能没有任何障碍得攻击你了。当然这只是基本的安全模型,通过XSS等技术,如果你的代码有漏洞的话,还是可能受到来自不同域的恶意代码的攻击。

但跨域的需求却一直都在,为了跨域,勤劳勇敢的程序猿们想出了许许多多的方法,例如,jsonP、代理文件等等。但这些做法增加了许多不必要的维护成本,而且应用场景也有许多限制,例如jsonP并非XHR,所以jsonP只能使用GET传递参数。

Web应用跨域访问解决方案汇总

CORS协议

如今的JS大有一统天下的趋势,浏览器已经成了大多应用最好的安身之所。哪怕在移动端也有各种Hybird方案,在本地文件系统的Web页面,也有需要获取外部数据的需求,而这些需求也必然是跨域的。在寻找跨域解决方案时,发现了最优雅解决方案就是HTML5带来了的“Cross-Origin Resource Sharing”的新特性,来赋予开发者权力决定资源是否允许被跨域访问。

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

跨域资源共享CORS详解

CROS常见header

CORS具有以下常见的header

Access-Control-Allow-Origin: http://abc.com  Access-Control-Max-Age: 3600Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUTAccess-Control-Allow-Headers: x-requested-with
"Access-Control-Allow-Origin"表明它允许 "http://abc.com" 发起跨域请求,如果允许所有域名则填写“*”"Access-Control-Max-Age"表明在3600秒内,不需要再发送预检验请求,可以缓存该结果(上面的资料上我们知道CROS协议中,`一个AJAX请求被分成了第一步的OPTION预检测请求和正式请求`)"Access-Control-Allow-Methods"表明它允许POST, GET, OPTIONS, DELETE, PUT的外域请求"Access-Control-Allow-Headers"表明它允许跨域请求包含x-requested-with头

解决方案

在项目中新建一个类,代码如下:

package com.test.crossorigin;

import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Component;

@Componentpublic class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {        HttpServletResponse response = (HttpServletResponse) res;        response.setHeader("Access-Control-Allow-Origin", "*");        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");        response.setHeader("Access-Control-Max-Age", "3600");        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");        chain.doFilter(req, res);    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

再配置web.xml,使得过滤器生效

<filter>     <filter-name>cors</filter-name>     <filter-class>"CLASS_PATH".SimpleCORSFilter</filter-class> </filter> <filter-mapping>     <filter-name>cors</filter-name>     <url-pattern>/*</url-pattern> </filter-mapping>

接下来前端就可以像往常一样使用AJAX请求获得资源了,完全不需要做出什么改变。

原文地址:https://www.cnblogs.com/friendlysong/p/10528489.html

时间: 2024-10-10 01:22:47

前后端分离之跨域问题的相关文章

【js】【跨域问题】前后端分离的跨域问题

最近在研究nodejs,php的前后端分离相关东西,在调用接口的时候碰到一些跨域的问题,经过一段时间的摸索,总结出来的一些东西 php采用的是yii框架,登录的机制或者调用接口都需要前端传递cookie进去,但是nodejs的axios接口等默认是不会传递cookie的 跨域解析:浏览器请求非本域名的网站资源,如果目标服务器没有设置跨域的情况下,浏览器是会阻止用户的请求的 跨域的解决途径:可以配置后端服务转发的机制绕开跨域问题:也可以直接配置目标服务器的跨域配置 配置转发 搭建一个和前端处于同一

vue前后端分离解决跨域问题

用Vue-cli脚手架搭建了个demo,前后分离就有跨域问题的出现. vue-clie搭建demo步骤(传送门):https://www.cnblogs.com/wangenbo/p/8487764.html 我自己在网上找了2个接口做测试: CSDN:https://www.csdn.net/api/articles?type=more&category=home&shown_offset=1524276761019196&first_view=false 掘金:https://

前后端分离 ajax 跨域 session 传值 (后端使用 node)

前端:ajax访问时要加上"xhrFields: {withCredentials: true}" ,实现session可以传递 后端:Access-Control-Allow-Credentials 设置为 true:同时 Access-Control-Allow-Origin 必须指定 url npm 安装 express.body-parser.express-session.svg-captcha 后台代码: 1 var express = require('express')

前后端分离,跨域问题

解决跨域问题 1. 什么是跨域 1.1.不同域名的资源访问,存在跨域 1.2.同一个域名不同端口的资源访问,也属于跨域 1.3二级域名不同的资源访问,也属于跨域 只要域名(ip)和端口号有一样不同,那么都是跨域 http://localhost:8080 前端系统 发送Ajax取后端系统获取数据 http://localhost:80   后端系统 以上的两个地址也是跨域 2.跨域问题 跨域不一定会有跨域问题. 因为跨域问题是浏览器对于ajax请求的一种安全限制,也可以说是浏览器的同源策略 同源

前后端分离开发,跨域访问的apche设置

1,如何让Apache支持跨域访问呢? 步骤: 修改httpd.conf,windows中对应的目录是:C:\wamp\bin\apache\Apache2.4.4\conf\httpd.conf 把LoadModule headers_module modules/mod_headers.so 前面的注释删除 修改  改为:  即: <Directory />    AllowOverride none    Require all granted    Header set Access-

解决傻瓜式前后端分离前端跨域访问的问题

版本号49之后的chrome跨域设置chrome的版本升到49之后,跨域设置比以前严格了,在打开命令上加--disable-web-security之后还需要给出新的用户个人信息的目录.众所周知chrome是需要用gmail地址登录的浏览器,登录后就会生成一个存储个人信息的目录,保存用户的收藏.历史记录等个人信息.49版本之后,如果设置chrome浏览器为支持跨域模式,需要指定出一个个人信息目录,而不能使用默认的目录,估计是chrome浏览器怕用户勿使用跨域模式泄露自己的个人信息(主要是cook

前后端分离的跨域请求问题解决

因为工作中接触到了,就记录下来. 主要是两个jar包的使用 可以自己看看源码或是其他对内部方法讲解的资料. web.xml配置. 原文地址:https://www.cnblogs.com/helloworld-yjh/p/9689465.html

vue+springboot前后端分离工程中跨域问题的解决

vue+springboot前后端分离工程中跨域问题的解决 假如是在同一台机器上开发,前后端分离的工程中出现跨域问题的原因是,前端工程和后端工程运行在不同的端口上.只要协议.域名.端口有一个不同就会产生跨域问题,所以在前端工程中请求后端的接口时就会因为端口不同而产生跨域问题. 一.解决跨域的原理 假设前端A要去访问服务器C,可以在A和C之间之间设置一个代理B,A访问C时先访问B,再由B代为请求C并把请求结果返回给A,这样就可以解决跨域问题.其中需要保证的是A访问B和B访问C都不能存在跨域. 二.

前后端分离,解决跨域问题及django的csrf跨站请求保护

1. 前后端分离解决跨域问题 解决跨域调用服务并设置headers 主要的解决方法需要通过服务器端设置响应头.正确响应options请求,正确设置 JavaScript端需要设置的headers信息 方能实现: 关于跨域,前端会先发送OPTIONS请求,进行预检,检查后端是否允许前端设置的相应的请求头,请求内容 function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie