> For the complete documentation index, see [llms.txt](https://docs.vwo.gaprise.jp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.vwo.gaprise.jp/testing/troubleshooting/prju8je8el.md).

# トラブルシューティング：SafariでのITPの問題の解決する

Safariは最近、トラッキング防止機能（ITP）[2.1](https://webkit.org/blog/8613/intelligent-tracking-prevention-2-1/)、[2.2](https://webkit.org/blog/8828/intelligent-tracking-prevention-2-2/)、および[2.3](https://webkit.org/blog/9521/intelligent-tracking-prevention-2-3/)を導入しました。これにより、サイト間でユーザーのアイデンティティを確立するトラッカーの機能が低下されます。

ITPバージョン2.1では、訪問者のブラウザに作成されたCookie（document.cookieを使用）の有効期限は7日間です。

2.1に加え、ITPバージョン2.2では、Webサイトのユーザーが装飾されたURL、すなわちクロスドメイントラッキング機能で分類されたドメインを使用し、クエリー文字列やフラグメントを持つ場合、Webサイト上のCookieは24時間以内に失効します。

2.2に加え、ITPバージョン2.3では、クロスドメイントラッキング機能で分類されたドメインのユーザーがクエリー文字列やフラグメントを持つ場合、ファーストパーティの非CookieWebサイトデータは、ユーザーがWebサイトとやり取りしない7日後に失効するように設定されています。

### **iOSでのITPマッピング** <a href="#id-1" id="id-1"></a>

* ITP 機能のバージョン2.1が、iOS12.2のSafariおよびmacOSのSafari12.1に搭載されています（MojaveおよびHigh Sierra用）。「<https://webkit.org/blog/8613/intelligent-tracking-prevention-2-1/>」<br>
* macOSのMojave 10.14.5のSafariに ITP 機能のバージョン2.2が搭載されています。「<https://webkit.org/blog/8828/intelligent-tracking-prevention-2-2/>」<br>
* ITP 機能のバージョン2.3は、iOS 13のSafari、iPadOSベータ版、およびMacOSのSafari 13に搭載され、Catalina、Mojave、およびHighSierraに対応しています。「<https://webkit.org/blog/9521/intelligent-tracking-prevention-2-3/>」

### **ITPがVWOのトラッキングに与える影響** <a href="#id-2" id="id-2"></a>

VWOでは、すべての訪問者追跡情報がCookieに保存されます。VWOのクライアントサイドのテストプラットフォームでは、document.cookieメソッドを使用してこれらのCookieが作成されます。ITP 2.1以降、この情報をCookieからファーストパーティのローカルストレージに移動させました。

ITP 2.2では、Webサイトの訪問者が装飾されたURL、すなわちクロスドメイントラッキング機能で分類されたドメインを使用し、クエリー文字列やフラグメントを持つ場合、document.cookieを介して作成されるCookieの保存期間の上限は24時間です。

また、ITP 2.3では、Webサイトへの訪問者が装飾されたリンクのとき、ファーストパーティの非Cookie保存期間が7日間に制限されるため、ローカルストレージオプションも損なわれてしまいます。

ITP 2.2で発生した装飾されたリンクの問題により、すべてのファーストパーティCookieとローカルストレージデータの有効期限は、それぞれ24時間と7日です。つまり、ローカルストレージを使用している場合でも、キャンペーンに参加してから7日後にWebサイトに戻った訪問者は、新規訪問者として識別されます。これにより、ユニーク訪問者数を膨らませ、A/Bテストキャンペーンのコンバージョン率に歪みを与える可能性があります。これは、VWOによって収集されたすべてのデータに影響を与えます。

**例えば、**&#x30D5;ァネルは3つのステップがあり、訪問者が8日目に最後のステップを完了したとき、訪問者がファネルの全ステップを完了しても、ファネルのフローは完了しないことになります。これは、ユーザーのジャーニーを通して収集されたデータは、（ローカルストレージに保存されていたため）7日後に期限切れになる可能性があるからです。この後、訪問者は新規訪問者とみなされ、データ収集は最初から開始されます。同じユーザーが複数回追跡されるため、結果があいまいになります。リンクの装飾によるクロスサイトトラッキングの詳細は、「[ITP 機能2.2](https://webkit.org/blog/8828/intelligent-tracking-prevention-2-2/)」をご参照ください。

これは、7日後にWebサイトにアクセスした同じ訪問者が、以前に表示されたものとは異なるバリエーションの同じテストが提供される可能性があることも意味します。そのため、一貫性のない体験が生まれ、キャンペーンの精度に影響を与える可能性があります。また、クロスドメイントラッキング機能で分類されたドメインからWebサイトに来た訪問者で、URLにクエリー文字列またはフラグメント識別子があるとき、サイトを以前訪問してから24時間を少しでも超えたら、新規訪問者として扱われます。これは、どのバリエーションがユーザーに表示されたかに関する情報がCookieに保存されているためです。

### **SafariでのITPの問題を解決する** <a href="#id-3" id="id-3"></a>

**キャンペーンが1つのドメインまたは同じドメインの複数のサブドメインで実行されているとき**

クロスドメイントラッキング機能で分類されたドメインでキャンペーンが実施されており、クエリー文字列やフラグメントがある場合、以下のようなケースが見られます。

* ユーザーが以前の訪問から7日以内にWebサイトのいずれかのサブドメインにアクセスし続けると、すべてが予想どおりに機能します。
* ただし、ユーザーが以前サブドメインにアクセスしてから7日以上経過している場合は、予想とおりに機能しない場合もあります。

**例えば**、ユーザーが以前サブドメインにアクセスしてから7日以上経過している場合、以前訪問したときのVWOCookieのデータが更新されていない可能性があります。これにより、次のシナリオが含まれる可能性がありますが、これらに限定されない問題が発生する可能性があります。

* ユーザーが新しいサブドメインにアクセスしたとき、新規訪問者として追跡されます。
* ユーザーが以前にファネルの一部であったら、再度ファネルに含まれる可能性があります。
* そのユーザーはリピーターとして追跡されるかもしれませんが、そのコンバージョンが再び記録されるかもしれません。

Cookie**同期エンドポイントをインストールする**

ITP関連の問題を回避するには、サーバーにCookie同期エンドポイントをインストールして、VWOによって作成されたCookieを読み取り、無限の有効期限（例えば10年間）を設定する必要があります。VWOでは、PHP、Node.js、Java、Pythonなどのさまざまなバックエンド言語でこのスニペットが提供されます。

コードスニペットの追加は、2つのステップで行います。

**1.**&#x30B7;ンクコードファイルを作成し、作業する言語に対応した拡張子で保存します。**例えば、**&#x50;HPの実装を選択したとき、\[ファイル名]を \[<ファイル名>.php] とする必要があります。

**注：**.NET実装を選択したとき、同期コードをコントローラーファイルに追加します。

**2.**&#x30B3;ードスニペットのsyncUrl属性に同期ファイルのURLを入力し、このコードスニペットファイルをVWOSmartCodeの前に追加します。

***PHP SCRIPT コードスニペット***

PHPを実装しているとき、VWO SmartCodeの前に以下の設定をインストールする必要があります。

```
window.VWO = window.VWO || [];
VWO.push(['config', {
  storage: {
    // enter the full url of the sync script
    syncUrl: 'https://somewebsite.com/sync.php'
  }
}]);
```

次のスクリプト例を追加すると、Cookieの有効期限が切れず、VWOはローカルストレージに依存する必要は全くありません。

```
<?php
if (array_key_exists('HTTP_ORIGIN', $_SERVER)) {
    header('Access-Control-Allow-Origin: ' . $_SERVER["HTTP_ORIGIN"]);
} else {
    header('Access-Control-Allow-Origin:*');
}
header('Access-Control-Allow-Credentials:true');
foreach ($_COOKIE as $key => $value) {
    if (preg_match('/^(_vis_opt|_vwo)/', $key)) {
        // Expire any VWO cookies after 10 years.
        
        // Set the cookie on root path so that it's accessible on all paths
        
        // Set the domain to .eTld+1 e.g. for a.abc.com eTld would be abc.com. So domain should be .abc.com. If you are not sure about what is the value in your case, you can contact the VWO support team.
        setcookie($key, $value, time() + 3600 * 24 * 10 * 365, "/", ".<eTld+1>");
        // setcookie($key, $value, time() + 3600 * 24 * 10 * 365, "/", ".abc.com");
    }
}
echo 1; // success
?>
```

view raw[cookieDontExpire.php](https://gist.github.com/vwo-kb/e53ee47b50ab22a43a241c04c8c201b4#file-cookiedontexpire-php)　hosted with ❤ by [GitHub](https://github.com/)

***NODE JSのコードスニペット***

Node.jsを実装しているとき、VWO SmartCodeの前に以下の設定をインストールする必要があります。

```
window.VWO = window.VWO || [];
VWO.push(['config', {
  storage: {
    // enter the full url of the sync script
    syncUrl: 'https://somewebsite.com/sync'
  }
}]);
```

FileName: Sync.js, Node.js Implementation

```
/**
 * The following functions reads cookies created by VWO from request and syncs them back to client
 */
function syncCookies(request, response) {
    let cookies = request.headers.cookie;
    const responseHeaders = {
        "Access-Control-Allow-Credentials": true,
        "Access-Control-Allow-Origin": request.headers.origin ? request.headers.origin : "*"
    };
    if (!cookies) {
        response.writeHead(200, responseHeaders);
        response.end("1");
        return;
    }
    cookies = cookies.split(";");
    cookies.forEach(function(cookie) {
        const cookieParts = cookie.trim().split("="),
            name = cookieParts[0],
            value = cookieParts[1];
        if (name.search(/^(_vis_opt_|_vwo)/) !== -1) {
            responseHeaders["Set-Cookie"] = responseHeaders["Set-Cookie"] || [];
            // Expire any VWO cookies after 10 years.
            // Set the cookie on root path so that it's accessible on all paths
            // Set the domain to .<eTld+1>
            responseHeaders["Set-Cookie"].push(`${name}=${value};path=/;domain=.<eTld+1>;expires=${new Date(Date.now() + 10 * 365 * 24 * 3600 * 1000).toGMTString()}`);
            // e.g. for a website example.abc.com eTld would be "com". So eTld+1 would be "abc.com".
            // If you are not sure about what is the value in your case, you can contact the VWO support team.
            // responseHeaders["Set-Cookie"].push(`${name}=${value};path=/;domain=.abc.com;expires=${new Date(Date.now() + 10 * 365 * 24 * 3600 * 1000).toGMTString()};`);
        }
    });
    response.writeHead(200, responseHeaders);
    response.end("1");
}
// If you are using express framework e.g., you can use the above code as follows
app.get('/sync', function(request, response) {
    return syncCookies(request, response)
});
```

***SYNC .NET コードスニペット***

サーバーコントローラ

```
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System.Text.RegularExpressions;

namespace YourApplication.Controllers {
 public class CookiesController: Controller {

  [HttpGet]
  public IActionResult SyncCookies() {
   foreach(string cookieName in Request.Cookies.Keys) {
    string pattern = @ "^(_vis_opt_|_vwo).*";

    Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
    Match match = regex.Match(cookieName);

    if (match.Success) {
     string cookieValue = Request.Cookies[cookieName];

     CookieOptions option = new CookieOptions();
     // Expire any VWO cookie after 10 years.
     UInt64 expiry = 315360000000 UL;

     option.Expires = DateTime.Now.AddMilliseconds(expiry);
     // Set the cookie on root path so that it's accessible on all paths
     option.Path = "/";

     // Set the domain to .eTld+1 e.g. for a.abc.com eTld would be abc.com. So domain should be .abc.com. If you are not sure about what is the                            value in your case, you can contact the VWO support team.
     option.Domain = ".<eTld+1";

     Response.Cookies.Append(cookieName, cookieValue, option);
    }
   }

   Response.Headers.Add("Access-Control-Allow-Origin", "*");

   return Ok();
  }
 }
}
```

NetStandard2.0をお使いのときは、上記のコードを次のように使用することができます。

```
app.UseMvc(routes => {
 routes.MapRoute("cookies", "sync", defaults: new {
  controller = "Cookies", action = "SyncCookies"
 });
});
```

**複数のドメインでキャンペーンを実施しているとき**

VWOでは、Safariで、デフォルトでサポートされていないため、現在、複数のドメインにわたる追跡が対応されていません。

**注：**&#x57;ebサイトの訪問者が装飾されていないリンク、すなわちクエリー文字列やフラグメント形式のクエリーを持たないドメインである場合は、追加で必要なことはありません。7日間の制限は、すべてのクライアントサイドCookieデータのローカルストレージへの自動フォールバックで処理されます。

Cookie**同期エンドポイントでの現在の制限事項**

Cookie同期エンドポイントをインストールすることで、他の動作がうまく行われますが、VWOでのアンケートはファーストパーティのローカルストレージの制限のため影響があります。例えば、訪問者が7日以内にアンケートのすべての質問を完了しなかった場合、ローカルストレージのデータは7日後に期限切れになるため、アンケートの進行状況は失われます。また、その情報はCookie同期エンドポイントの後にCookieで利用可能であるため、その訪問者は新規訪問者として考慮されることはありません。この情報は失われるため、再度アンケートを表示することはありません。

### **よくある質問(FAQ)** <a href="#id-4" id="id-4"></a>

Cookie**同期のコードはどのように機能しますか？**

このロジックにより、すべてのVWOクライアントサイドCookieをサーバーサイドCookieに変換され、その有効期限が10年に設定されます。7日間の有効期限はサーバー側のCookieには適用されないため、追跡やその他のVWO機能は正常に機能します。

**VWOの**Cookie**は10年まで有効期限なしということですか？**

**いいえ**、フロントエンドでCookieを手動で失効させるロジックを追加しました。VWOでは、すべてのCookieの有効期限が値とともに保存され、Cookieを削除するタイミングが自動的に判断されます。

**セキュリティ上の脅威やCookieの漏洩について心配する必要がありますか？**

**いいえ、**&#x56;WOでは同期スクリプトに送信されたCookieを受信または保存されないため、セキュリティ上の懸念やCookieの漏洩の脅威はありません。すべてのロジックは独自のサーバーにあり、そこで保存されます。
