【问题标题】:Sharing images from whatsapp to angular app via Share_Target not working通过 Share_Target 将图像从 whatsapp 共享到 Angular 应用程序不起作用
【发布时间】:2020-11-30 14:28:51
【问题描述】:

我正在尝试将图像从 WhatsApp 共享到我的应用程序。 每当我将 WhatsApp 中的媒体项目共享到我的应用程序时,它都会点击 webmanifest 文件并以 /nav/emergencyRegister 路由为目标。 我确信它会到达目标路线,因为当我从 WhatsApp 共享图像时,它会在前端打开相同的路线。

这是我的 manifest.webmanifest 文件中的代码。

{
  "name": "Apoms",
  "short_name": "Apoms",
  "theme_color": "#1976d2",
  "background_color": "#fafafa",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "gcm_sender_id": "275309609166",
  "share_target": {
    "action": "/nav/emergency-register",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "title": "name",
      "text": "description",
      "url": "link",
      "files": [
        {
          "name": "images",
          "accept": "image/*"
        },
        {
          "name": "videos",
          "accept": "video/*"
        }
      ]
    }
  }

但是在 EmergencyRegisterComponent.ts 文件中,我不知道如何访问应该在路由参数中的图像。

这是我在紧急注册页面.component.ts 文件中的代码。

import { Component, OnInit } from '@angular/core';
import { PrintTemplateService } from '../../print-templates/services/print-template.service';
import { CaseService } from '../services/case.service';
import { EmergencyRegisterTabBarService } from '../services/emergency-register-tab-bar.service';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
    // tslint:disable-next-line:component-selector
    selector: 'emergency-register-page',
    templateUrl: './emergency-register-page.component.html',
    styleUrls: ['./emergency-register-page.component.scss'],
})
export class EmergencyRegisterPageComponent implements OnInit {
    constructor(private printService: PrintTemplateService,
        private route: ActivatedRoute,
        private caseServie: CaseService,
        private tabBar: EmergencyRegisterTabBarService) {}

    ngOnInit() {

        this.printService.initialisePrintTemplates();

// I printed the this.route and tried to find the image in there but failed.
// Also used params,querParams from route.
        const data = this.route.snapshot.paramMap.get('files');
        console.log(data);

    }
}

我还尝试从here 扩展现有的服务工作者。 我创建了一个新的 service worker 文件 apoms-sw.js

importScripts('./ngsw-worker.js');


self.addEventListener('fetch', event=>{
  console.log(event);
});

在我的 app.module.ts 中

@NgModule({
    declarations: [AppComponent, ConfirmationDialog, TreatmentRecordComponent],
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        AppRoutingModule,
        MatDialogModule,
        NavModule,
        HttpClientModule,
        MaterialModule,
        ServiceWorkerModule.register('apoms-sw.js', { enabled: environment.production }),
        AngularFireDatabaseModule,
        AngularFireAuthModule,
        AngularFireMessagingModule,
        AngularFireStorageModule,
        AngularFireModule.initializeApp(environment.firebase)
    ],
    exports: [],
    providers: [
        DatePipe,
        { provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true },
        // { provide: LOCALE_ID, useValue: 'it-IT' },
        { provide: ErrorHandler, useClass: UIErrorHandler }
    ],
    bootstrap: [AppComponent],
})

我可以看到文件在远程调试过程中被命中,但它没有触发 fetch 事件侦听器。 因此,如果有人能告诉我如何访问路线随附的图像。会很棒的。

【问题讨论】:

    标签: angular typescript whatsapp


    【解决方案1】:

    所以这里的问题之一是 Angular 创建了自己的服务工作者。一个应用程序只能有一个服务工作者。您可以在this 问题中了解更多信息。

    Service Worker 一个接一个地触发重复的函数,直到其中一个调用 respondWith。并且由原始服务(ngsw-worker.js)worker 定义的 fetch 函数中有一个 respondWith,这意味着没有进一步的消息被传递。这意味着您需要在 ngsw-worker fire 中的 fetch 函数之前定义任何函数。您可以在this 问题中阅读更多内容。

    所以 webmanifest 应该是这样的,它属于你的 webmanifest 的根目录:

    "share_target": {
        "action": "/nav/emergency-register",
        "method": "POST",
        "enctype": "multipart/form-data",
        "params": {
          "files": [
            {
              "name": "image",
              "accept": "image/*"
            },
            {
              "name": "video",
              "accept": "video/*"
            }
          ]
        }
      },
    

    然后您需要一个新文件,其中包含您的 fetch 函数并导入 service worker。首先定义你的 fetch 函数很重要:

    self.addEventListener('fetch', event => {
    
      // Handle the share_target shares
      if (event.request.method === 'POST') {
    
        // Make sure we're only getting shares to the emergency-register route
        const path = event.request.url.split("/").pop();
    
        if(path === "emergency-register"){
    
            //Get the images and videos from the share request
            event.request.formData().then(formData => {
    
                // Find the correct client in order to share the results.
                const clientId = event.resultingClientId !== "" ? event.resultingClientId : event.clientId;
                self.clients.get(clientId).then(client => {
    
                    // Get the images and video
                    const image = formData.getAll('image');
                    const video = formData.getAll('video');
    
                    // Send them to the client
                    client.postMessage(
                        {
                            message: "newMedia",
                            image: image,
                            video: video
                        }
                    );
                });
            });
        }
      }
    });
    
    
    importScripts('./ngsw-worker.js');
    

    然后在您的 app.component 中,您可以定义将捕获发布消息的函数,如果您使用 firebase 消息传递或其他向客户端发布消息的函数,则需要小心区分它们:

    // Set up to receive messages from the service worker when the app is in the background.
    navigator.serviceWorker.addEventListener('message', (event:MessageEvent) => {
    
        if(event.data.hasOwnProperty('image')){
    
            this.emergencyTabBar.receiveSharedMediaItem(event.data);
        }
    
        if(event.hasOwnProperty('data')){
    
            this.messagingService.receiveBackgroundMessage(event.data?.firebaseMessaging?.payload);
       }
    
    });
    

    【讨论】:

    • 您说要在新文件中添加self.addEventListener('fetch', event => {。我应该在哪里添加?在项目的根目录中?我无法将我的应用程序视为我的 Angular 应用程序的共享目标,但我可以将它安装在我的手机上。清单是否负责在共享抽屉上显示应用程序?还是我需要正确配置 addEventListener 才能显示?
    • @shinz4u 您已将此文件添加到根文件夹中。是的,清单将负责在共享抽屉中显示应用程序。如果这不起作用,请向您的代码提出问题,我会回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 2012-01-11
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多