跳到主要内容

跨应用跨域设置

跨应用方式

基调听云Web与基调听云APM之间跨应用通过两种方式:

  1. 对于页面, 由Server端在页面的返回头中通过Set-Cookie写入特殊的Cookie值,携带Server端性能数据和其他信息,由Web探针获取并在获取后删除对应的Cookie, 随后在Web数据上传时携带Server端相关信息。
  2. 对于Ajax请求, 首先由Web探针在请求头中加入指定的请求头X-Tingyun,Server端收到后相应返回指定的返回头X-Tingyun-Data,Web探针通过X-Tingyun-Data获取相关Server性能数据。

本文档主要描述第二种场景在实际部署中的配置。

如何判断跨域

Web探针在满足下面条件时才会在Ajax请求头中加入X-Tingyun

  • Ajax跨应用开关打开。
  • Ajax请求与页面地址同域
  • Ajax请求与页面地址不同域但在跨域域名设置中配置了请求端域名。

同域,即同源。在跨应用场景下指页面地址和Ajax请求地址的协议域名端口号必须完全相同。当Ajax请求地址与页面地址不同时,称为跨域请求。

示例1: 协议不同不是同域

页面: http://tingyun.com/index.html
Ajax: https://tingyun.com/api/getUser

Ajax地址是https协议,与页面http不同, 不是同域。

示例2: 相同父域,子域不同,不是同域

页面: http://doc.tingyun.com/index.html
Ajax: http://api.tingyun.com/getUser

Ajax域名为api.tingyun.com与页面的doc.tingyun.com不同,不是同域。

示例3: 端口号不同不是同域

页面: http://10.128.1.32:8080/index.html
Ajax: http://10.128.1.32:9090/api/getUser

页面端口号8080, Ajax端口号9090, 不是同域。

浏览器由于安全原因, 对在脚本(JS)中发起的跨域请求进行限制。对于Web探针添加自定义请求头(X-Tingyun),和获取自定义返回头(X-Tingyun-Data)的场景都会有限制:

  • 跨域下增加自定义请求头, 会触发预验请求(options请求), 需要服务端返回相关的返回头允许添加自定义请求头。
  • 跨域下不能在客户端脚本直接获取自定义返回头(此处指JS探针获取X-Tingyun-Data),同样需要服务端返回相关的返回头允许获取自定义返回头。

如果服务端配置不正确, 直接添加请求头会严重影响系统业务。报表中配置跨域域名后,会导致Web探针在符合规则的跨域Ajax请求中添加X-Tingyun请求头, 如果此时服务端配置不正确会有严重后果, 因此打开跨域域名配置之前必须保证服务端配置已经生效

跨域Ajax跨应用配置流程图

下面描述了跨域Ajax跨应用配置操作的详细步骤,必须按顺序操作,保证每一步完成后再进行下一步。

步骤1: 配置Nginx

以服务端为Nginx示例, 下面配置示例为服务端需要添加的返回头和相关处理。建议在用户后端Api Nginx的server级别嵌码, 如果有精确配置需求,也可以配置在对应的location下。

Nginx 配置示例:

server {
listen 5999;
server_name localhost;

# 配置开始
add_header 'Access-Control-Allow-Origin' '$http_origin';
add_header 'Access-Control-Allow-Headers' 'X-Tingyun';
add_header 'Access-Control-Expose-Headers' 'X-Tingyun-Data';
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Max-Age' 1728000;
if ($request_method = 'OPTIONS') {
return 204;
}
# 配置结束

location /server/ {
proxy_pass http://localhost:8089/;
}
}

配置说明:

  • Access-Control-Allow-Origin

    必须但需根据实际情况, 值为请求的域。此项是单一值,如果用户环境已经添加不能重复添加。

  • Access-Control-Allow-Headers

    必须项, 需要确保包含 X-Tingyun

  • Access-Control-Expose-Headers

    必须项, 需要确保包含X-Tingyun-Data

  • Access-Control-Allow-Methods

    必须项,但需根据实际情况, 如客户端环境已经添加则不需要再重复增加(此项即使重复增加也不会报错)。

  • Access-Control-Max-Age

    可选, 浏览器端可根据此返回头缓存Options请求。

其他说明:

Access-Control 系列头支持通配符,但当客户端发送携带凭证请求时 (例如 XHR: xhr.withCredentials = true;) 通配符失效, 因此为了简化问题排查,需要精确指定X-TingyunX-Tingyun-Data, 避免使用通配符。

Access-Control-Allow-Headers 参考资料

Access-Control-Expose-Headers 参考资料

步骤2: 验证服务端配置是否正确

注意:此步骤不通过不能进行第3步!

通过curl命令访问用户Ajax请求, 指定请求方式为OPTIONS, 并携带Web探针携带的请求头X-Tingyun:


curl -I -H 'X-Tingyun: c=B|key;x=random' -X OPTIONS [URL]

示例:

[tingyun@apm3-saas-alpha-001 ~]$ curl -I -H 'X-Tingyun: c=B|key;x=random' -X OPTIONS http://192.168.5.149:5999/server/server-test
HTTP/1.1 204 No Content
Server: nginx/1.19.4
Date: Tue, 24 Nov 2020 07:22:49 GMT
Connection: keep-alive
Access-Control-Allow-Headers: X-Tingyun
Access-Control-Expose-Headers: X-Tingyun-Data
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
Access-Control-Max-Age: 1728000

判断配置成功:

  1. 返回结果中需要确认Nginx配置已经生效, 确认Access-Control-Allow-Headers包含 X-TingyunAccess-Control-Expose-Headers包含X-Tingyun-Data
  2. 返回头相关配置项不能重复 。

步骤3: 配置跨域域名

  1. 在左侧导航栏中点击概览,在目标应用后点击设置,进入应用设置页面。依次点击APM设置> 添加跨域域名,添加后保存设置。如Ajax请求地址为https://api.tingyun.com/getUser, 需配置域名api.tingyun.com。 配置支持包含关系, 即Ajax请求域名包含配置的域名也会生效, 即上述情况配置tingyun.com也会生效。
  2. 如果是下载探针手动嵌码,需要重新下载探针嵌码。如果是引用外链嵌码,则此时配置已经生效。
  3. 验证探针内容是否已经下发跨域域名配置。

下载探针文件或访问探针外链, 搜索cors_domains, 找到最后一项匹配,查看后续的数组中是否包含之前配置的跨域域名内容。

步骤4: 验证跨应用是否生效

打开用户系统, 使用Chrome开发者工具请求模块或抓包工具,查看用户系统之前的跨域Ajax请求是否满足:

  1. 请求头包含X-Tingyun, 返回头包含X-Tingyun-Data

  2. 开发者工具控制台没有获取X-Tingyun-Data的报错, 即没有下面报错内容。

如果正常,探针端已经可以正常抓取跨应用数据。

常见问题排查

  • 如果没有携带X-Tingyun请求头, 查看客户端当前引用的探针内容, 按步骤3 第3步查看是否已经成功下发跨域配置。某些客户端可能需要清理浏览器缓存。
  • 如果跨域Ajax请求包含X-Tingyun请求头,但不包含X-Tingyun-Data返回头, 需要排查请求头是否已经被server探针接收或server探针端排查确认返回头是否正常下发。