PWA:强制window.open打开浏览器,而不是PWA。

问题描述 投票:0回答:1

我建立了一个ASP.NET Core应用程序和一个angular前端。Angular应用程序有 @angular/pwa node包的设置,所以它是一个可以安装在androidwindows上的渐进式网络应用,表现得像一个本地应用。

我已经用Microsoft.AspNetCore.Identity.设置了外部登录(微软,谷歌,Facebook,Twitter)。在我的Angular应用中,我打开了一个弹出式的外部登录页面。

  this.authWindow = window.open(`${this.baseUrl}/web/v2/Account/${this.action}/${medium}/${this.platform}`, null, 'width=600,height=400');

弹出窗口的url指向一个ASP.NET Core端点,我在那里设置了... return Challenge() 调用,返回特定外部提供者(Microsoft、Google、Facebook、Twitter)的登录页面。

在Windows的Chrome浏览器中,您点击一个按钮,触发window.open()以打开一个带有外部登录页面的窗口。登录成功后,你会被重定向到回调页面,这是一个剃须刀页面,它向包含angular应用的主窗口发送消息。该消息正在被处理,弹出窗口正在被关闭。

問題

我在安卓版Chrome浏览器上使用网站时,可以把PWA安装成app,在我的安卓主页上增加一个图标。当我打开PWA并点击按钮打开弹出窗口时,弹出窗口正在打开我的PWA的弹出窗口,所以没有问题。

当我在android上打开Chrome浏览器并访问网站时,在安装PWA的同时,该 window.open() 调用并没有打开Chrome浏览器的弹出窗口,而是试图打开Progressive Web App的弹出窗口。既然如此,PWA里面的弹出窗口就无法通知Chrome浏览器中的网站登录成功(duh...)。

但是,当PWA没有安装时,就会出现 window.open() 可以正常工作,并在Chrome浏览器中自行打开弹出窗口。

所以底线是在安卓系统上安装了PWA。我希望能够调用 window.open() 从我的网站在Chrome浏览器内,并让它打开弹出窗口在 Chrome浏览器 而不是PWA。

我尝试过的事情

1) 修改ngsw-config.json。

{
  ...,
  "navigationUrls": [
    "/**",
    "!/**/*.*",
    "!/**/*__*",
    "!/**/*__*/**",
    "!/web/v2/Account/connect/**/**",
    "!/web/v2/Account/add/**/**"
  ]
}

2)打开窗口,用 target='_system'

this.authWindow = window.open(`${this.baseUrl}/web/v2/Account/${this.action}/${medium}/${this.platform}`, '_system', 'width=600,height=400');

3)打开窗口,用 target='_blank'

this.authWindow = window.open(`${this.baseUrl}/web/v2/Account/${this.action}/${medium}/${this.platform}`, '_blank', 'width=600,height=400');

4)打开窗口,用 target='_blank' 而没有baseUrl,只是一个绝对路径。

this.authWindow = window.open(`/web/v2/Account/${this.action}/${medium}/${this.platform}`, '_blank', 'width=600,height=400');

但是所有的技巧似乎都是一样的,仍然在PWA中打开窗口。

progressive-web-apps window.open
1个回答
0
投票

我最终创建了一个子域,托管我的外部登录端点(ExternalLogin、ExternalLoginCallback、AddExternalLogin、AddExternalLoginCallback)。

[Controller]
[Route("web/v2/[controller]")]
public class AccountController : Controller
{
    private IAccountService accountService;
    public AccountController(IAccountService accountService)
    {
        this.accountService = accountService;
    }

    ...

    // GET: web/Account/providers
    [AllowAnonymous]
    [HttpGet("providers", Name = "web-v2-account-external-providers")]
    public async Task<ActionResult<IEnumerable<string>>> Providers()
    {
        var result = await accountService.GetProviders();
        return Ok(result);
    }

    // GET: web/Account/connect/{provider}
    [AllowAnonymous]
    [HttpGet("connect/{medium}/{provider}", Name = "web-v2-account-external-connect-challenge")]
#if RELEASE
    [Host("external.mintplayer.com")]
#endif
    public async Task<ActionResult> ExternalLogin([FromRoute]string medium, [FromRoute]string provider)
    {
        var redirectUrl = Url.RouteUrl("web-v2-account-external-connect-callback", new { medium, provider });
        var properties = await accountService.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
        return Challenge(properties, provider);
    }

    // GET: web/Account/connect/{provider}/callback
    [HttpGet("connect/{medium}/{provider}/callback", Name = "web-v2-account-external-connect-callback")]
#if RELEASE
    [Host("external.mintplayer.com")]
#endif
    public async Task<ActionResult> ExternalLoginCallback([FromRoute]string medium, [FromRoute]string provider)
    {
        try
        {
            var login_result = await accountService.PerfromExternalLogin();
            if (login_result.Status)
            {
                var model = new LoginResultVM
                {
                    Status = true,
                    Medium = medium,
                    Platform = login_result.Platform
                };
                return View(model);
            }
            else
            {
                var model = new LoginResultVM
                {
                    Status = false,
                    Medium = medium,
                    Platform = login_result.Platform,

                    Error = login_result.Error,
                    ErrorDescription = login_result.ErrorDescription
                };
                return View(model);
            }
        }
        catch (OtherAccountException otherAccountEx)
        {
            var model = new LoginResultVM
            {
                Status = false,
                Medium = medium,
                Platform = provider,

                Error = "Could not login",
                ErrorDescription = otherAccountEx.Message
            };
            return View(model);
        }
        catch (Exception ex)
        {
            var model = new LoginResultVM
            {
                Status = false,
                Medium = medium,
                Platform = provider,

                Error = "Could not login",
                ErrorDescription = "There was an error with your social login"
            };
            return View(model);
        }
    }

    // GET: web/Account/logins
    [Authorize]
    [HttpGet("logins", Name = "web-v2-account-external-logins")]
    public async Task<ActionResult<IEnumerable<string>>> GetExternalLogins()
    {
        var logins = await accountService.GetExternalLogins(User);
        return Ok(logins.Select(l => l.ProviderDisplayName));
    }

    // GET: web/Account/add/{provider}
    [Authorize]
    [HttpGet("add/{medium}/{provider}", Name = "web-v2-account-external-add-challenge")]
#if RELEASE
    [Host("external.mintplayer.com")]
#endif
    public async Task<ActionResult> AddExternalLogin([FromRoute]string medium, [FromRoute]string provider)
    {
        var redirectUrl = Url.RouteUrl("web-v2-account-external-add-callback", new { medium, provider });
        var properties = await accountService.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
        return Challenge(properties, provider);
    }

    // GET: web/Account/add/{provider}/callback
    [Authorize]
    [HttpGet("add/{medium}/{provider}/callback", Name = "web-v2-account-external-add-callback")]
#if RELEASE
    [Host("external.mintplayer.com")]
#endif
    public async Task<ActionResult> AddExternalLoginCallback([FromRoute]string medium, [FromRoute]string provider)
    {
        try
        {
            await accountService.AddExternalLogin(User);
            var model = new LoginResultVM
            {
                Status = true,
                Medium = medium,
                Platform = provider
            };
            return View(model);
        }
        catch (Exception)
        {
            var model = new LoginResultVM
            {
                Status = false,
                Medium = medium,
                Platform = provider,

                Error = "Could not login",
                ErrorDescription = "There was an error with your social login"
            };
            return View(model);
        }
    }
}

当在PWA中运行时,window.open仍然会在你的PWA中的嵌入式浏览器中打开链接,而当从浏览器中运行时,window.open仍然会在一个新的浏览器窗口中打开链接(不在你的PWA中)。在这两种情况下,我仍然能够访问打开器来发送消息(window.opener.postMessage)。

© www.soinside.com 2019 - 2024. All rights reserved.