标签:source 分组 解决 jquer 必须 get info 简单的 访问
跨域无疑是一个老生常谈的话题了,而且也是每个前端同学都会遇到的问题,那么跨域你真的讲的清吗,不妨看看这些
一、什么是跨域?
由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一个与当前页面地址不同即为跨域
1、同源策略:
2、同源策略含义:
<script><img><iframe><link><video><audio>
等带有src属性的标签可以从不同的域加载和执行资源。flash、java applet、silverlight、googlegears
等浏览器加载的第三方插件也有各自的同源策略,只是这些同源策略不属于浏览器原生的同源策略,如果有漏洞则可能被黑客利用,从而留下XSS攻击的后患二、为什么会跨域?
浏览器之所以要对跨域请求作出限制,是出于安全方面的考虑,防止被不法分子利用利用跨域请求来发动 CSRF攻击 。
三、跨域解决方案
1、JSONP
在jQuery中最常用的就是Ajax 的JSONP了,利用 <script><img><iframe>
等标签不受同源策略限制,可以从不同域加载并执行资源的特性,来实现数据跨域传输。JSONP由回调函数和数据两部分组成,使用与服务端约定好回调函数名称,服务端接收到请求后返回一段JavaScript代码,这段代码调用约定好的回调函数,并将数据作为参数进行传递,页面接收到这段代码后就会立即执行这个回调函数,解析传递来的数据
2、NGINX代理
代理是用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端
注意点:如果代理的是https协议的请求,那么你的proxy首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则请求无法成功。
3、CORS
CORS即跨源资源共享 Cross-Origin Resource Sharing(CORS),是一个新的W3C标准,允许服务端声明那些网站有权限访问哪些资源,即允许浏览器向声明了CORS的跨域服务器,发出XMLHttpReuest请求,从而解决同源策略的限制,本文则着重讲解CORS办法
当非简单请求浏览器发生跨域时,我们会看到浏览器有一个OPTION 类型的请求,这叫预检请求,在规范中规定,对于非简单的请求,浏览器必须首先使用 OPTION 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求,在服务器确定允许后,才发起实际的HTTP请求。对于简单请求、非简单请求以及预检请求的详细资料可以阅读,HTTP访问控制
那么怎么避免触发预检请求呢
上文说了,非简单请求才会触发预检请求,所以只要保证请求是简单请求即可,注意这里的简单请求不单单指请求方式,详情请看简单请求,简单请求的请求方式包含GET、POST、HEAD,但是在实际中POST请求也会预检请求,那是因为只有当请求的Content-Type值是 text/plain,
multipart/form-data,
application/x-www-form-urlencoded三者之一时才被认为是简单请求
下面以Vue + axios项目实例做跨域讲解
在Vue中当axios配置 axios.defaults.baseURL =‘******‘后,本地代理就不再生效,那么想要解决跨域的问题首先需要后端服务允许跨域,然后前端保证发出的是简单请求
后端服务配置:
protected void writeStr(HttpServletResponse resp,HttpServletRequest request, String str) { resp.setHeader("Access-Control-Allow-Origin", "*"); resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); resp.setHeader("Access-Control-Max-Age", "3600"); Enumeration<String> headersEnum = ((HttpServletRequest) request).getHeaders("Access-Control-Request-Headers"); StringBuilder headers = new StringBuilder(); String delim = "";
//取消OPTIONS预检请求 while (headersEnum.hasMoreElements()) { headers.append(delim).append(headersEnum.nextElement()); delim = ", "; } resp.setHeader("Access-Control-Allow-Headers", headers.toString()); resp.setContentType("text/html; charset=UTF-8"); try { resp.getWriter().write(str); LoggerUtils.getLogger().info("==================="); LoggerUtils.getLogger().info("return msg:{}", str); } catch(IOException e) { LoggerUtils.getLogger().error(e.getMessage(),e); } }
Access-Control-Allow-Origin
响应首部中可以携带这个头部表示服务器允许哪些域或者所有域可以访问该资源,语法: Access-Control-Allow-Origin: <origin> | * ,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。
Access-Control-Allow-Methods
该首部字段用于预检请求的响应,指明实际请求所允许使用的HTTP方法。语法: Access-Control-Allow-Methods: <method>[, <method>]*,
Access-Control-Max-Age
该首部字段用于预检请求的响应,指定了预检请求能够被缓存多久,语法: Access-Control-Max-Age: <delta-seconds>
,
前端配置:
保证前端请求即可。未完待续......
标签:source 分组 解决 jquer 必须 get info 简单的 访问
原文地址:https://www.cnblogs.com/weichen913/p/10085714.html