为了解决
window.open()
方法中referer
参数导致的非法请求问题,需要确保在使用该方法时不携带referer
参数,或者正确配置服务器以接受带有referer
的请求。这样可以避免因referer
信息导致的请求被拒绝,从而正常打开目标页面。
问题现象:
最近在我们的页面上,当需要跳转到第三方页面时,我们通常使用
window.open()
方法进行打开。这种方法之前一直运行良好,但最近在尝试打开某些特定的第三方页面时,却遭遇了"非法请求"错误。
在-申请明细 - 有一个字段业务系统单号
,当点击穿透链接本应该跳转至详细信息页面,却出现404。
无法正常打开,提示404。
然而,当页面刷新或者重新打开后,访问又恢复正常。
问题出现在通过我们的系统直接打开第三方的OA系统时,操作无法成功。
关联缺陷:
【【192环境】点击业务系统单号,打开OA出差申请单报错】www.tapd.cn/54290569/bu...
排查步骤:
-
初步推断问题可能与请求参数有关,细致地对比了请求参数。
-
尝试打开浏览器的开发者工具(F12)来观察请求参数。但是由于使用了
window.open
方法,页面跳转速度太快,导致无法及时打开开发者工具来捕捉到错误信息(页面已经显示404错误
)。
调试技巧建议(一):
在源代码中直接 将
window.open
改<a>
链接
- 如果问题在于
window.open
导致页面跳转太快,无法及时打开开发者工具进行调试,可以尝试修改源代码。 - 将原本通过点击触发的
window.open
方法替换为一个直接的<a>
链接,并为其指定一个目标窗口名称(例如target="window1"
)。 - 这样,点击链接时将在新的浏览器标签页或窗口中打开目标URL,从而可以更容易地打开F12开发者工具进行调试。参考如下示例:
html
<!-- 替换前 -->
<button onclick="window.open('your_third_party_link')">打开第三方页面</button>
<!-- 替换后 -->
<a href="your_third_party_link" target="window1">打开第三方页面</a>
这样做的好处是:通过将目标设置为 window1
,每次点击链接都会在同一个命名的窗口或标签页中打开页面。
这样,如果你事先已经打开了F12开发者工具,你就可以在该工具中持续监控和查看新的网络请求头和请求体,而不会因为页面跳转太快而错过调试信息。
这对于捕捉和分析在页面加载过程中发生的网络请求非常有帮助。
- 左侧为正常打开时的参数,右侧为无法正常打开时的参数。
通过上图可以发现,两次请求中,能打开的链接的是没有包含referer
地址和sec-fetch-site
,
为了验证这一假设,可以在发起请求之前,通过修改浏览器的开发者工具或使用拦截请求的浏览器插件(如ModHeader等)来手动删除或修改这些请求头参数,如果没有工具就用下面提供的妙招吧。
调试小妙招二:
使用
curl
命令行工具模拟请求并修改请求体参数,用于验证是否因为某项参数导致的问题。如果你怀疑是请求体中的某个参数导致了问题,可以使用
curl
命令行工具来模拟发送请求,并逐一修改或删除请求体中的参数以验证你的假设。curl
是一个强大的工具,它允许你从命令行发送各种类型的HTTP请求。以下是一个基本的
curl
命令示例,用于发送一个POST请求:
bashcurl -X POST "http://example.com/api/endpoint" -H "Content-Type: application/json" -d '{"param1":"value1", "param2":"value2"}'
- 选择打开的链接-复制-以cURL(bash)格式复制
- 复制内容如下
bash
curl 'https://oa.xxxx.cn/westvalley/loginsso/LoginSSO2RequestInfo.jsp?requestid=7997094&userid=08210184&isPC=1&signature=C43F93475043E1C1A6ED7052DE86826B' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
-H 'Accept-Language: zh-CN,zh;q=0.9' \
-H 'Connection: keep-alive' \
-H 'Cookie: acw_tc=0b32821217058905180295285e2be5a4f718598e2705e4c65e3ba096d8ab24; __clusterSessionCookieName=3F13DA0D914646D43E16730C618CD6BA; ecology_JSessionid=aaadweF2sioLagx81EN0y; loginidweaver=47875; languageidweaver=7; JSESSIONID=aaadweF2sioLagx81EN0y' \
-H 'Referer: https://fssc.xxxx.com.cn:8086/' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: same-site' \
-H 'Sec-Fetch-User: ?1' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
--compressed
放到可以执行curl命令的机器上尝试(其实一般电脑上装了git bash
就可以了)。
-
复制 - 粘贴 - 回车运行
返回的页面是404
-
以下是取消了
Referer
的参数
bash
curl 'https://oa.xxxx.com.cn/westvalley/loginsso/LoginSSO2RequestInfo.jsp?requestid=7997094&userid=08210184&isPC=1&signature=C43F93475043E1C1A6ED7052DE86826B' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
-H 'Accept-Language: zh-CN,zh;q=0.9' \
-H 'Connection: keep-alive' \
-H 'Cookie: acw_tc=0b32821217058905180295285e2be5a4f718598e2705e4c65e3ba096d8ab24; __clusterSessionCookieName=3F13DA0D914646D43E16730C618CD6BA; ecology_JSessionid=aaadweF2sioLagx81EN0y; loginidweaver=47875; languageidweaver=7; JSESSIONID=xaaadweF2sioLagx81EN0y' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: same-site' \
-H 'Sec-Fetch-User: ?1' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
--compressed
-
复制 - 粘贴 - 回车运行
-
这一次响应的是一个302的重定向地址,没有404了
问题总结
-
如果你遇到的404问题是由于目标站点OA实施了防盗链措施,那么当浏览器在跳转时自动添加
referer
请求头时,如果referer
不在目标站点的允许列表中,请求就会被拒绝,导致404错误。 -
为了解决这个问题,需要在目标站点OA的防盗链设置中添加你的域名(例如
https://fssc.xxxxxx.cn:8086/
)。 -
这样,当从你的域名发起请求时,目标站点将识别
referer
并允许访问。
解决办法:
一、在html全部修改掉
浏览器跳转会往header
里加上Referer
值,来标识这次访问的来源页面。
而OA网站对Referer非oa得情况下进行了拦截导致
在页面中强行加这一段
html
<meta name="referrer" content="no-referrer">
但是这一改就是全系统改了。
关于referrer值的设置可以参考
developer.mozilla.org/zh-CN/docs/...
二、修改window.open的打开方式(本次修改方法)
js
window.open('javascript:window.name;',
'<script>location.replace("'+你的跳转url+'")<\/script>');
三、window.open新窗口打开
js
window.open(link, '_blank', 'noopener,noreferrer,resizable');
四、不改代码改服务器配置
由于目标站点OA实施了防盗链措施,防盗链设置可以在服务器配置中进行,例如在Apache服务器中可以使用 .htaccess
文件,或者在Nginx服务器中可以使用 nginx.conf
文件。
以下是一个简单的示例,在Apache服务器中允许特定的 referer
:
apache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^https://fssc.xxxxxx.cn:8086/ [NC]
RewriteRule .* - [F]
</IfModule>
在这个例子中,如果 referer
不是 https://fssc.xxxxxx.cn:8086/
,请求将被拒绝。
可以修改服务器配置可能需要服务器管理员权限。
整理编辑不易,点赞加油!