目录
问题现象与描述
重庆软航科技有限公司提供了一套针对针对word、excel等流式文件转换成PDF版式文件并进行版式文件在线签章的一个方案,给方案做了一个应用示例,该示例在完成流式文件转成PDF版式文件之后展示了一个在线阅读转换后PDF文件并在线签章的相关功能。
但是在tongweb上部署之后发现该示例完成word转PDF功能后的在线查看PDF时功能异常,浏览器中F12调试 发现状态信息不为200而是 CORS error,如下图所示:
该功能对应的请求 已配置请求头信息:Access-Control-Allow-Origin为*
查看详细的信息时发现:Referrer Policy为same-origin:
且 该应用在tomcat中 部署时并未出现此类异常,因此可以断定示例本身是没有问题的。
猜想可能是由于tongweb的配置影响了。
说一下示例所需要的资源部署情况:将其需要的软航电子签章系统、软航版式文档签批系统、软航文档转换系统以及软航提供的结合这几个一体化应用示例都部署到了同一台服务器的tongweb上了。
解决办法
打开tongweb 管理控制台,在【WEB容器配置】中选择【HTTP通道管理】选择【tong-http-listener】:
下拉到【其他设置】:
在其他设置这里有一个:禁用HTTP请求方法
将禁用的OPTIONS方法放开(勾选取消掉):
之后 重启tongweb ,再试就可以解决 CORS error 问题了。
原理解析
什么是CORS
CORS:即跨域(Cross-Origin Resource Sharing, CORS)是一种安全策略,由浏览器 enforced,限制跨域 HTTP 请求,指在一个域下的网页尝试访问另一个域下的资源。在web应用中服务器地址、端口、项目但凡有一个不同,访问的资源不是自己的,那就属于跨域。例如部署在A服务器上的appA项目,那么 在appA中访问 B服务器上的appB ,或者访问服务器A上的其他应用appx 都属于跨域。
跨域问题主要发生在浏览器端,服务器端由于协议设计的原因,不存在跨域问题。浏览器端跨域请求主要涉及到**同源策略(Same-Origin Policy),**同源策略限制了从一个源加载的文档或脚本与另一个源的资源进行交互。
浏览器跨域请求限制
浏览器默认是禁用跨域请求的,主要体现在以下方面:
(1)HTTP 请求方法:通常只允许 GET、POST 和 HEAD 请求。
(2)HTTP 头信息:无法发送 Cookie、HTTP 认证信息(如 Basic Auth)等。
(3)HTTP 响应:无法读取非简单响应内容,如 JSONP 只支持 JSON 格式。
跨域问题解决方法
(1)同源策略:通过 HTML5 的 window.postMessage 方法实现跨域通信。
(2)CORS:服务器设置 Access-Control-Allow-Origin 等响应头,允许特定域访问资源。
(3)JSONP:通过动态创建 script 标签,利用其不受同源策略限制的特性实现跨域请求。
(4)代理服务器:通过设置一个代理服务器,实现请求转发和响应返回。
跨域请求流程
(1)浏览器发送预检请求(Preflight Request):询问服务器是否允许该跨域请求。
(2)服务器响应预检请求:如果允许,返回相应的 CORS 响应头。
(3)浏览器发送实际请求:携带 CORS 响应头信息,如 Access-Control-Allow-Origin。
浏览器请求分类解析
浏览器发送预检请求以及实际发送请求时就需要对浏览器请求做分类。 浏览器请求使用的是HTTP协议时,请求分类主要有:
HTTP 1.0: GET、POST、HEAD
HTTP 1.1: GET、POST、HEAD、[OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT]
在本次遇到的问题中已经设置好了 携带 CORS 响应头信息,如 Access-Control-Allow-Origin ,且tomcat中异常,可以肯定应用本身是设定好的。而服务器响应预检请求的时候实际是由 tomcat、tongweb这种应用服务器中间件来处理的。那么也就是说但凡浏览器发送的请求类型被应用服务器本身拦截了,那么必然是会出现跨域问题的,这时就需要让应用服务器允许对应的请求才行。
http请求方法简介
上述提到的浏览器请求分类,实际就是常说的http请求方法。主要http 请求方法介绍如下:
- get:用于从服务器获取资源,例如请求一个网页或图片。这是最常见的请求方法,用于读取或下载数据。
- head:与GET方法类似,但服务器在响应中只返回HTTP头部信息,不返回实际数据。这通常用于检索资源的元信息。
- post:用于向服务器提交数据以供处理,例如表单提交或文件上传。POST请求通常用于添加新资源或更新现有资源。
- put:用于更新服务器上的现有资源。客户端发送PUT请求时,会包含一个指定资源的新表示,服务器将用这个新表示替换原有资源。
- delete:用于请求服务器删除指定的资源。
- connect:用于建立到服务器的隧道化连接,通常用于代理服务器。
- options:用于获取关于资源所支持通信选项的信息。服务器在响应中会包含一个Allow头,列出支持的所有请求方法。
- trace:用于追踪请求-响应的传输路径,通常用于调试目的。
根据浏览器调试的信息可以看到当前问题的网络信息里 确实是有两次请求 :第一次请求时 http请求的方法类型为:options 也就是前文提到的浏览器发送预检请求(Preflight Request):询问服务器是否允许该跨域请求。
第二次才是 实际请求:
所以在tongweb 管理控制台里 设置 【WEB容器配置】中选择【HTTP通道管理】选择【tong-http-listener】里开放Options方法 就可以解决当下遇到的问题了。