首页 > 其他分享 >Access control allow origin 简单请求和复杂请求

Access control allow origin 简单请求和复杂请求

时间:2023-06-28 14:32:57浏览次数:47  
标签:control origin 浏览器 请求 Access http 跨域


错误信息

XMLHttpRequest cannot load http://web.image.myqcloud.com/photos/v2/10008653/bhpocket/0/?sign=4FcLKd5B8…p4SkFVUEJtZ1omZT0xNDQ0NzExMDE5JnQ9MTQ0NDcwNzQxOSZyPTEzMDMyMDgzOTAmdT0wJmY9.No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

 

分析:

Access control allow origin直译过来就是"访问控制允许同源",这是由于ajax跨域访问引起的。所谓跨域就是,在a.com域下,访问b.com域下的资源;出于安全的考虑,浏览器允许跨域写,而不允许跨域读写就是上行,发送请求,send request,读就是下行,接受响应,receive response;理解了这两条规则,以下现象我们也就能理解了;

 

1、表单默认提交(get、post)、超链接访问域外的资源,这是允许的,因为在点击按钮/超链接时,浏览器地址已经变了,这就是一个普通的请求,不存在跨域;

2、ajax(借助xmlhttprequest)跨域请求,这是被禁止的,因为ajax就是为了接受接受响应,这违背了,不允许跨域读的原则

3、jsonp属于跨域读且形式限制为GET方式,它利用了script标签的特性;这是允许的。因为浏览器把跨域读脚本,当作例外,类似的img、iframe的src都可以请求域外资源

 

解决方案:

方案1,给chrome浏览器添加参数,--disable-web-security

Access control allow origin 简单请求和复杂请求_html

Access control allow origin 简单请求和复杂请求_跨域_02

 

方案2

a,

非IE浏览器,利用xmlhttprequest,在request header添加origin:本域名地址,通常不需要手动添加,浏览器会动添加

IE浏览器,利用XDomainRequest发送请求,它会自动封装header中添加origin

b,response header添加access-control-allow-origin:*

 

跨域演示及代码

验证过程,首先访问http://本机ip:port/project_name/a.jsp,然后,a.jsp发送ajax请求,http://localhost:port/project_name/b.jsp,这样就产生了跨域的问题。

a.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>跨域演示</title>
<script type="text/javascript" src="jquery-1.11.2.js"></script>
<script type="text/javascript" src="jquery.form.js"></script>
</head>

<script type="text/javascript">
$(document).ready(function() {
	
	$.getJSON('http://localhost/test_maven/b.jsp', function(data) {
		alert("request succeed");
	});
});
</script>
</body>

 

 

b.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%

response.setHeader("Access-Control-Allow-Origin", "*");
response.getWriter().write("hahahhaha");
%>

 

如果注释掉response.setHeader("Access-Control-Allow-Origin", "*");,那么就会出现access control allow origin错误;使用通配符*,允许所有跨域访问,所以跨域访问成功

但是,请注意使用通配符*,会允许来自任意域的跨域请求访问成功,这是比较危险的,所以在生产环境通常会做更精确控制;

 

简单请求

上述请求是简单请求,只要添加了Access-Control-Allow-Origin:*,就会访问成功,如果是复杂请求,我们需要更进一步的处理,才能成功。这里先解释一下什么是简单请求和复杂请求。

 

Simple requests

A simple cross-site request is one that meets all the following conditions:

The only allowed methods are:
GET
HEAD
POST
Apart from the headers set automatically by the user agent (e.g. Connection, User-Agent, etc.), the only headers which are allowed to be manually set are:
Accept
Accept-Language
Content-Language
Content-Type
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded
multipart/form-data
text/plain

 

 

 

简单来说,符合上述条件的都是“简单请求”,除了简单请求就是“复杂请求”。

 

 

复杂请求

在正式post之前,浏览器会先发出一个options请求(也叫preflight),同时header带上origin还有Access-Control-Request-*:**之类的头,服务器响应会返回相应的access-control-allow-origin,如果匹配,那么浏览器就会发送正式post,否则就会出现上述错误。这也解答了,跨域访问时,我们明明发送的post请求,失败的话,查看chrome network会发现是options方法的原因。

根据上述过程,后台方法额外需要options方法,以下是测试样例。

这里的content-type不属于(application/x-www-form-urlencoded,multipart/form-data,text/plain)中的任何一种,所以是复杂请求。

 

 

$.ajax({
		   
           type: "post",
           url: "http://localhost/test_maven/a_action",
           contentType: "application/json",
           dataType:  "json",
           success: function(){
				alert("request succeed");
			}
       });

 

 

 

 

 

 

@RequestMapping(value = "/a_action",
			method=RequestMethod.OPTIONS)
	public void aActionOption(HttpServletResponse response ) throws IOException{
		
		System.out.println("option execute.....");
		response.setHeader("Access-Control-Allow-Headers", "accept, content-type");
		response.setHeader("Access-Control-Allow-Method", "POST");
		response.setHeader("Access-Control-Allow-Origin", "http://192.168.8.36");
	}

 

@RequestMapping(value = "/a_action",method=RequestMethod.POST)
	public void aAction(HttpServletResponse response ) throws IOException{
		
		System.out.println("a_action execute.....");
	}

第一次是options请求,http options请求跟get、post、head等一样,都属于http的请求方法,options方法,用来获取服务器端某url支持的方法,response header中allow标志支持的方法

 

 

 

Access control allow origin 简单请求和复杂请求_html_03

 

第二次才是真正的请求

 

Access control allow origin 简单请求和复杂请求_html_04

 

这个方案是利用了w3c的最新规范,所以该方案依赖浏览器的实现。

 

总结:

出现Access control allow origin错误,说明是跨域请求失败!浏览器发送请求成功,同时浏览器也接收到响应了,但是限制了XmlHttpRquest接收请求,不会让xmlhttprequest接受到响应,并且在js控制台报错。这也就是我们在网络控制台(Network)能看见http 状态码是200,但是在js控制台(Console)出现js错误的原因。

 

参考:

《白帽子讲web安全》P28、P144 cross origin resource sharing的内容

跨域post请求实现方案小结--转

CORS

 

9年全栈开发经验,请关注个人公众号

Access control allow origin 简单请求和复杂请求_Access_05

 

 

 

标签:control,origin,浏览器,请求,Access,http,跨域
From: https://blog.51cto.com/u_15561616/6571889

相关文章

  • 如何通过抓包分析EasyCVR级联时不回复上级平台的invite请求?
    EasyCVR平台基于云边端协同架构,可支持多协议、多类型的海量设备接入与分发,平台既具备传统安防视频监控的能力,也具备接入AI智能分析的能力,在线下均有大量应用。有用户反馈,在级联时,使用EasyCVR作为下级平台,将摄像头接入后再转推给上级平台,但是上级平台却无法播放,请求我们协助排查。由......
  • EasyCVR级联后上级在线,请求播放显示端口不可达是什么原因?
    EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力,比如:视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级......
  • DevExpress GroupControl面板收缩展开
    1#regionGroupControl面板缩进展开绑定2privatevoidBindGroupControl(DevExpress.XtraEditors.GroupControlgroupControl)3{4DevExpress.XtraEditors.ButtonsPanelControl.ButtonImageOptionsbuttonImageOptions1=newDevExpres......
  • 如何在.net6webapi中记录每次接口请求的日志
    为什么在软件设计中一定要有日志系统?在软件设计中日志模块是必不可少的一部分,可以帮助开发人员更好的了解程序的运行情况,提高软件的可靠性,安全性和性能,日志通常能帮我们解决如下问题:调试和故障排查:日志可以记录程序运行时的各种信息,包括错误,异常,警告等,方便开发人员在出现问题时......
  • Spring中什么时候用@Resource,@service,及Spring注解@Component、@Repository、@Servic
    参考资料http://crabboy.iteye.com/blog/339840文章正文<context:annotation-config/> <context:component-scanbase-package=”com.eric.spring”> component-scan标签默认情况下自动扫描指定路径下的包(含所有子包),将带有@Component、@Repository、@Service、@Controller标签......
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Secureboot
    regaddHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Secureboot/vAvailableUpdates/tREG_DWORD/d0x10/f命令是用于在注册表中添加一个名为"AvailableUpdates"的DWORD值,并将其设置为十六进制值"0x10"。此操作需要管理员权限才能执行。这个命令的作用是向......
  • 模拟HTTP测试post请求与get请求方式的工作原理与抓包分析
    一,工作原理与简介HTTP请求是客户端向服务器发送请求的过程,常见的HTTP请求方法有GET和POST。如下图,HTTP新建请求过程(1)GET请求的工作原理是,客户端向服务器发送一个请求,请求中包含要获取的资源路径和参数,服务器根据路径和参数返回相应的资源。GET请求可以在URL中传递参数,参数以键......
  • 跨站请求伪造攻击CSRF(四)
    一、跨站请求伪造攻击概述 跨站请求攻击(Cross-siterequestforgery),是指攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作。用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本XSS相比,XSS利用的是用户对指定网......
  • 前端Vue自定义加载中loading加载结束end组件 可用于分页展示 页面加载请求
    前端Vue自定义加载中loading加载结束end组件可用于分页展示页面加载请求,请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13219效果图如下:实现代码如下:cc-paging使用方法<!--加载中用法isLoading:是否加载isEnd:是否结束加载--><cc-paging:isLoad......
  • Nginx配置origin限制跨域请求 转载
    按照等保要求,跨域的不安全性,需要修复。这个需要根据客户端传递的请求头中的Origin值,进行安全的跨站策略配置,目的是对非法的origin直接返回403错误页面。漏洞复现复现方式为在Header中指定Origin请求头,看是否可以请求成功。能够请求成功,说明未对请求头进行控制,有漏洞。cu......