React项目中利用iframe嵌入传递登录态的“吐个槽”SDK

最近需要在项目中的某个页面嵌入“吐个槽”,项目用的是react全家桶。
要求是携带登录状态信息,因此用组件的形式嵌入,过程中遇到了一些坑,在此记录一下。

吐个槽接入文档(官方出品):

https://tucao.qq.com/helper/configLogonState

重点

  • 利用form表单传递登录信息,必须保证在提交前form表单拿到正确的登录信息
  • iframe必须有name值,form必须有target,且二者保持一致,否则form表单的默认跳转属性会打开新页面或者替换掉当前页面
问题一:

最初直接使用了官方提供的工具包tucao.js,看了一下源码,就自己实现了一下。没想到问题就来了,form表单提交会在iframe页面里打开一个链接,同时也会新开一个标签页打开链接。试了很多种方法,都没能解决,最后改用iframe中嵌入form,再传入登录信息的方式才解决;

问题二:

form表单提交放到了componentDidMount函数中,有时拿不到更新后的state,因此用了一个定时器,保证能够拿到最新的登录信息

全部代码:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import actions from '@/action'
import './index.less'

// 请填写自己公司的产品ID
const productId = 1212

class Feedback extends Component {
  constructor(props) {
    super(props)
    this.state = {
      isLoading: false,  // 避免重复获取数据
      // 吐个槽提供的默认登录信息,三个字段都必填
      nickname: 'tucao_test',
      avatar: 'https://tucao.qq.com/static/desktop/img/products/def-product-logo.png',
      openid: '-1',
    }
  }

  componentDidMount() {
    this.props.loadUserInfo()

    // 等待setState数据成功后,再进行form表单提交,避免登录信息提交失败
    setTimeout(() => {
      this.complainForm.submit()
    }, 0)
  }

  // 获取登录信息
  componentWillReceiveProps(nextProps) {
    if (nextProps.staff && nextProps.staff.id && !this.state.isLoading) {
      const { name, avatar, id } = nextProps.staff
      this.setState({
        isLoading: true,
        nickname: name,
        avatar: avatar,
        openid: id,
      })
    }
  }

  render() {
    const { userInfo: { data: { staff }}} = this.props
    return (<div className="it-complain">
      {
        staff.id && <iframe
          className="complain-iframe"
          src={'https://support.qq.com/product/' + productId} // src为指定嵌入的吐个槽页面
          name="complain-iframe" // 必须有,为form表单提供target
        >
          <form
            method="post"
            action={'https://support.qq.com/product/' + productId}
            target="complain-iframe" // target值为iframe标签的name属性,避免action跳转到其他页面
            ref={(form) => { this.complainForm = form }}
          >
            <input type="hidden" name="openid" value={this.state.openid} />
            <input type="hidden" name="nickname" value={this.state.nickname} />
            <input type="hidden" name="avatar" value={this.state.avatar} />
            <button type="submit" />
          </form>
        </iframe>
      }
    </div>)
  }
}

const mapStateToProps = (state) => ({
  userInfo: state.userInfo,
})

const mapDispatchToProps = {
  loadUserInfo: actions.loadUserInfo,
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Feedback))

如果有更好的实现方法,欢迎讨论~

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 元素会创建包含另外一个文档的内联框架(即行内框架); 一、align 属性(不赞成) align属性规定ifram...
    puxiaotaoc阅读 19,906评论 0 14
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 28,403评论 1 45
  • 前端开发面试题 <a name='preface'>前言</a> 只看问题点这里 看全部问题和答案点这里 本文由我...
    自you是敏感词阅读 4,274评论 0 3
  • 前端开发面试题 面试题目: 根据你的等级和职位的变化,入门级到专家级,广度和深度都会有所增加。 题目类型: 理论知...
    怡宝丶阅读 7,410评论 0 7
  • 逍遥星期一阅读 2,910评论 0 0

友情链接更多精彩内容