ajax怎么读(不要再问我跨域的问题了)

精英怪
广告

前后端分离带来的跨域问题

ajax怎么读(不要再问我跨域的问题了)

1、什么同源策略?

同源指的是 "协议 + 域名 + 端口 “ 三个相同,即使两个不同的域名指向同一个IP地址,也是非同源。

同源策略是为了安全,确保一个应用中的资源只能被本应用的资源访问。否则,岂不是谁都能访问。

同源

http://www.domain.com/index http://www.domain.com/module/index

非同源

http://www.domain.com/index https://www.domain.com/module/index

http://www.domain.com/index http://www.domainb.com/module/path1

http://www.domaina.com/index http://www.domaina.com:8081/module/path1

两个相同的源之间浏览器是默认可以相互访问资源和操作DOM的。两个不同的源之间

若想要相互访问资源或者操作 DOM,那么会有一套基础的安全策略的制约。具体有如下两

方面的限制。

1. 安全性: 浏览器要防止当前站点的私密数据不会向其他站点发送

如当前站点的Cookie,LocalStorage,IndexDb 不会被发送到其他站点或被其他站点脚本读

取到无法跨域获取Dom,无法发送Ajax请求。

2. 可用性:大型站点的图片,音视频等资源,希望部署在独立服务器上,为缓解当前服务

的压力,开放某些特定的方式,访问非同源站点

如:<script><img><iframe><link><vedio>等,可以同src属性跨域访问

允许跨域提交表单/或重定向请求

解决方案

1.服务端解决

跨域请求分两种情况

a. 简单请求:

请求方法使用GET/HEAD/POST请求之一仅能使用CORS安全的头部,Accept,Accept-Language, Content-Language,Content-TypeContent-Type的值只能是:text/plain,multipart/form-data,application/x-

www-form- urlencoded三者其中之一

服务端解决方案:在http响应头中添加 Access-Control-Allow-Origin 头,值为信任的

站点。

/** * 简单请求1 * * @param response * @return * @throws IOException */ @RequestMapping(value = "/ajaxGetReq1", method = RequestMethod.GET) @ResponseBody public String ajaxGetReq(HttpServletResponse response) throws IOException { response.addHeader("Access-Control-Allow-Origin","http://localhost:8080"); return "plain text from ajax"; } /** * 简单请求2 * * @param user * @param response * @return * @throws IOException */ @RequestMapping(value = "/ajaxPostReq2", method = RequestMethod.POST) @ResponseBody public User ajaxPostReq2(User user, HttpServletResponse response) throws IOException { response.addHeader("Access-Control-Allow-Origin","http://localhost:8080"); return user; }

b. 复杂请求

不符合简单请求条件的即为复杂请求,访问跨域资源前,需要发起preflight预检请求

(OPTIONS请求)询问何种请求是被允许的,预检请求失败,则不会发起正式的业务请

求,预检请求成功,然后发起正式请求

SpringBoot解决方案:

1. 创建一个filter解决跨域。

@Component public 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, HEAD"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With"); chain.doFilter(req, res); } public void init(Filterconfig filterConfig) {} public void destroy() {} }

2.基于WebMvcConfigurerAdapter配置加入Cors的跨域

import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class CorsConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowCredentials(true) .allowedMethods("GET", "POST", "DELETE", "PUT") .maxAge(3600); } }

如果你想做到更细致也可以使用@CrossOrigin这个注解在controller类中使用。

这样就可以指定该controller中所有方法都能处理来自http:19.168.1.10:8080中的请求。

第一种Filter的方案也支持springmvc。

第二种常用于springboot。

2. 代理服务器,反向代理接口请求

apache http server / nginx

location /api { rewrite ^/api/(.*)$ /$1 break; proxy_pass http://localhost:8081/; }

3. jsonp 方式

<script> function clickButton() { var scriptTag = document.createElement("script"); scriptTag.src = "http://localhost:8081/jsonpReq"; document.body.appendChild(scriptTag); } function myFunc(myObj) { document.getElementById("demo").innerHTML = myObj.name; } </script>

发表评论

快捷回复: 表情:
AddoilApplauseBadlaughBombCoffeeFabulousFacepalmFecesFrownHeyhaInsidiousKeepFightingNoProbPigHeadShockedSinistersmileSlapSocialSweatTolaughWatermelonWittyWowYeahYellowdog
评论列表 (暂无评论,232人围观)

还没有评论,来说两句吧...