关于ios Universal Links apple-app-site-association文件 Not Found的问题

1. 背景说明

1.1 Universal Links 是什么


Support Universal Links
里面有说到 Universal Links 是什么、注意点、以及如何配置的。简单来说就是

当您支持通用链接时,iOS 用户可以点击指向您网站的链接,并无缝重定向到您安装的应用程序

大白话就是说,用户通过点击某个链接,可以直接唤起对应的app。提供这样功能的目的是为了吸引网络用户(俗称引流)。
(注意url的变化,一定是用户点击造成的!使用js触发是无效的)。

1.2 Universal Links 如何配置

在这里插入图片描述
简单的来说,配置Universal Links需要涉及到两方面:域名服务器和app:

① 域名服务器上要配置apple-app-site-association文件 (也被称为AASA文件)

创建apple-app-site-association文件后,将其上传到 HTTPS Web 服务器的根目录或子目录.well-known。该文件需要可通过 HTTPS 访问(无需任何重定向),地址为https:///apple-app-site-association或https:///.well-known/apple-app-site-association。接下来,您需要处理应用程序中的通用链接

即配置成以后,有3个链接要访问成功才可以:

https://你的域名.com/apple-app-site-association
https://你的域名.com/.well-known/apple-app-site-association
https://app-site-association.cdn-apple.com/a/v1/你的域名.com

最后一个链接是苹果CDN链接,可以理解为只要这个地址像下图一样返回正常,就说明我们配置的AASA文件没有问题
在这里插入图片描述

② app上要在Xcode的Associated Domains里面去配置applinks
在这里插入图片描述
在这里插入图片描述

两方面都要配置好,才能正常使用Universal Links 唤起app。配置OK后,可以在钉钉、微信、safari浏览器、扫描器等里面直接通过配置的域名唤起app。

2. 问题出现与调试

昨天17点的时候,发现Universal Links 无法正常唤起app了。打开那3个链接进行调试,发现只有前个是可以正常访问的。

https://你的域名.com/apple-app-site-association
https://你的域名.com/.well-known/apple-app-site-association
https://app-site-association.cdn-apple.com/a/v1/你的域名.com

第三个显示Not Found
在这里插入图片描述
在shell里面运行:

curl -v  https://app-site-association.cdn-apple.com/a/v1/你的域名.com

可以看到该请求的详细信息:
在这里插入图片描述

< Apple-Failure-Details: {"status":"405 Not Allowed"}
< Apple-Failure-Reason: SWCERR00101 Bad HTTP Response: 405 Method Not Allowed

3. 修复总结

  1. 这个Universal Links 之前一直能正常访问,ios app发版也没有动过相关配置。为什么就失效了呢

  2. 前2个链接是可以正常访问的,即apple-app-site-association的配置是ok的。问题出在最后一个连接上,Not Allowed 可能是我们的服务器不允许app-site-association.cdn-apple.com访问

  3. 联想到前几天服务器受到了攻击,所以运维调整了安全策略,有时候在我们的域名下可以安全提示。和运维确认以后,得知运维禁止了所有的国外ip访问

  4. 但是在运维放开以后,访问

https://app-site-association.cdn-apple.com/a/v1/你的域名.com

依然是 Not Found,似乎没有任何变动。

  1. 正好那个时间还有几分钟就下班了,还要取写每日云效和日报,就先没管这个了。今天上班以后,发现链接可以访问了。

    回想可能是缓存问题,之前配置AASA文件的时候,就了解到AASA文件文件是有缓存的,或者说是apple CDN的缓存。修改AASA文件以后,从https://app-site-association.cdn-apple.com/a/v1/ 访问可能不会马上更新。这个缓存具体时间不确定,可能是几小时或几天不等

  2. 也就是说即使我们修改了自己服务器上的apple-app-site-association文件,搭配app测试的时候,可能也不会马上达到我们想要的效果。 比如一开始我们在AASA文件里面是这样配置的:

     "paths": [
        "*"
      ]

      这代表当前域名下的所有url都会唤起我们的app


      但是如果修改一下:

        "paths": [
          "NOT *-wx-*",
          "*"
        ]

      这表示我们想当前域名下,含-wx-的url不会唤起app。但是当我们修改了AASA文件,并更新到服务器以后,同时确保服务器文件已更新。
      可能依然会发现,测试效果并非我们所预测的那样,包含-wx-的url依然会唤起app,此时查看

https://app-site-association.cdn-apple.com/a/v1/你的域名.com 

      会发现,依然是

     "paths": [
        "*"
      ]
  1. 同文件内容的缓存一样,我感觉我们在放开国外ip访问以后,https://app-site-association.cdn-apple.com/a/v1/ 或 apple CDN 并没有马上访问更新。所以当时没有生效,但是第二天缓存更新就生效了

4. 注意点

当用户在 Safari 中浏览您的网站并点击指向与当前网页位于同一域中的 URL 的通用链接时,iOS 会尊重用户最可能的意图并在 Safari 中打开该链接。

如果用户点击指向不同域中 URL 的通用链接,iOS 会在您的应用程序中打开该链接。

文档中这段话的意思是,如果我们有一个配置了Universal Links的域名A。
当时用户从A域名打开A域名的时候(A->A),不会触发APP跳转。
只有用户另外的B域名点击去到A域名的时候(B->A),才会触发APP的跳转,B域名是普通的域名。

### 实现 Flutter 中的深度链接 在移动应用开发中,深度链接是一种允许用户通过 URL 打开特定页面的技术。Flutter 提供了多种方法来支持深度链接功能,这使得开发者可以轻松集成并处理来自外部源(如浏览器或其他应用程序)的链接。 #### 配置 Android 平台上的深度链接 为了使 Android 应用能够响应深度链接请求,在 `AndroidManifest.xml` 文件中需要定义 intent 过滤器。以下是配置的一个典型例子: ```xml <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 接受 http 和 https 协议 --> <data android:scheme="http" android:host="www.example.com" android:pathPrefix="/deepLink" /> </intent-filter> </activity> ``` 此片段表明该活动可以通过访问类似于 `http://www.example.com/deepLink` 的网址启动[^1]。 #### iOS 上的 Universal Links 设置 对于 iOS 设备来说,则需启用关联域名服务并通过苹果开发者账户上传 AASA (Apple App Site Association) 文件到服务器根目录下或者 .well-known 子文件夹里。接着更新 Info.plist 添加相应条目如下所示: ```xml <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>example</string> </array> </dict> </array> <!-- Add Associated Domains capability --> <key>LSApplicationQueriesSchemes</key> <array> <string>https</string> </array> ``` 这里设置了一个自定义 scheme “example”,意味着任何以 `example://` 开头的 URI 将会触发这个 app 启动[^2]。 #### 使用 Flutter 插件管理深链事件 推荐使用官方插件 package:flutter/services 来监听这些进入点的变化情况。下面展示如何初始化以及捕获初始路由参数的过程: ```dart import 'package:flutter/material.dart'; import 'package:uni_links/uni_links.dart'; void main() { runApp(MyApp()); } class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { StreamSubscription? _sub; @override void initState(){ super.initState(); initUniLinks(); // 初始化 uni-links _sub = uriLinkStream.listen((Uri? uri){ if(uri != null && mounted){ setState(() {}); } }); } Future<void> initUniLinks() async{ try{ final initialUri = await getInitialUri(); if(initialUri != null){ debugPrint('initial link captured $initialUri'); }else{ debugPrint('no initial link found.'); } }catch(e){ debugPrint('error occurred while getting initial uri :$e'); } } @override Widget build(BuildContext context){ return MaterialApp( home:Scaffold( appBar:AppBar(title:Text("Deep Link Example")), body:Center(child:Text("Waiting for Deep Link...")) ) ); } } ``` 上述代码展示了如何利用第三方库 `uni_links` 处理不同平台间的统一链接逻辑,并且提供了对初次加载时可能存在的深层连接的支持。 ### 注意事项 当扩展网络规模或将设备放置于更广范围内的具体位置上增加节点数量的同时也要考虑安全性因素,防止恶意攻击者伪造合法路径欺骗用户的隐私数据泄露风险等问题发生。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值