使用html2Canvas生成图片跨域如何处理?

html-css016

使用html2Canvas生成图片跨域如何处理?,第1张

1.出现跨域的情况

这种情况只会出现在html2Canvas需生成的海报中的图片与当前环境不在同一个域下

2.解决方案

处理跨域,将接口返回的url处理为base64再进行处理或者后端直接返回base64

3.如何将url转换为base64?(利用canvas的toDataURL属性将url转为base64)

  function getImageBase64Data(imgSrc) {

    function getBase64(img) {

      let canvas = document.createElement("canvas")

      canvas.width = img.width

      canvas.height = img.height

      let ctx = canvas.getContext("2d")

      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

      let dataURL = canvas.toDataURL('image/jpeg')

      return dataURL

    }

    let baseUrl = new Promise(function (resolve, reject) {

      let image = new Image()

      image.crossOrigin = '*'// 图片处理跨域

      if (imgSrc.indexOf('data:image/jpegbase64') >-1) {

        image.src = imgSrc + '?v=' + Math.random()// 处理图片从缓存获取

      } else {

        image.src = imgSrc

      }

      image.onload = function () {

        let imageBase64Data = getBase64(image)

        resolve(imageBase64Data)

      }

    })

    return baseUrl

  }

4.使用html2Canvas生成海报

  const download = () => {

    let content = document.getElementById('promote-content')

    if (content) {

      html2canvas(content, { useCORS: true, allowTaint: true }).then(res => {

        const imgBase64 = res.toDataURL('image/jpeg')

        let link = document.createElement('a')

        link.style.display = 'none'

        link.href = imgBase64

        link.setAttribute('download', name + moment().format('YYYYMMDDHHmm'))

        document.body.appendChild(link)

        link.click()

        document.body.removeChild(link)

      })

    }

  }

一个请求url的** 协议、端口、域名 **其中任意一个与当前页面url不相同就是跨域

即:https://www.segmentfault.com:8080/  (http/https)协议、(segmentfault)主域名、(www)子域名、(8080)端口

是因为浏览器的同源策略的限制,同源策略是一种安全策略,同源指的是域名,协议,端口相同,会阻止一个域的js脚本和另一个域的内容进行交互。防止在一个浏览器中的两个页面产生不安全、异常的行为。

当然如果不同源的话会产生一定的限制:

【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

【2】无法接触非同源网页的 DOM

【3】无法向非同源地址发送 AJAX 请求

document.createElement(‘script’) 生成一个 script 标签,然后插 body 里而已。

JSONP的实现原理就是创建一个script标签, 再把需要请求的api地址放到src里. 这个请求只能用GET方法, 不可能是POST(向服务端传送数据)。

一种非正式传输协议,它会允许用户传递一个callback参数给服务端,然后服务端返回数据的时候会将这个callback参数作为函数名来包裹住JSON数据,然后客户端就可以随意的定义自己的函数来处理返回的数据了。

一般是后端在处理请求数据的时候,添加允许跨域的请求头信息,服务端设置Access-Control-Allow-Origin就可以,如果需要携带cookie,前后端都需要设置

window对象有个name的属性,在一个window下,窗口载入的页面都是共享一个window.name。

在a.html中,怎么把b.html页面加载进来,获取b.html的数据。在a.html页面使用iframe,可以去获取b.html的数据,然后在a.html页面中取得iframe获取得数据。

但是iframe想要获取b.html中的数据,只需要给这个iframe的src设为http://localhost:8000/b.html就可以,如果a.html想要得到iframe所获得的数据,也就是iframe的window.name的值,还要把这个iframe的src设成跟a.html页面同一个域才可以,不然a.html访问不到iframe里的window.name属性。

// 父窗口打开一个子窗口

    var openWindow = window.open('http://test2.com', 'title')

// 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)

    openWindow.postMessage('Nice to meet you!', 'http://test2.com')

调用message事件,监听对方发送的消息

// 监听 message 消息

    window.addEventListener('message', function (e) {

    console.log(e.source)// e.source 发送消息的窗口

    console.log(e.origin)// e.origin 消息发向的网址

    console.log(e.data)  // e.data  发送的消息

    },false)

    server{

    # 监听9099端口

    listen 9099

    # 域名是localhost

    server_name localhost

    #凡是localhost:9099/api这个样子的,都转发到真正的服务端地址http://localhost:9871

    location ^~ /api {

        proxy_pass http://localhost:9871

    }   

  }

// 请求的时候直接用回前端这边的域名http://localhost:9099,这就不会跨域,然后Nginx监听到凡是localhost:9099/api这个样子的,都转发到真正的服务端地址http://localhost:9871

fetch('http://localhost:9099/api/iframePost', {

  method: 'POST',

  headers: {

    'Accept': 'application/json',

    'Content-Type': 'application/json'

  },

  body: JSON.stringify({

    msg: 'helloIframePost'

  })

})

前端web开发html避免js的跨域访问的方法是后台服务端做域配置兼容处理。

1、在server端请求过滤的时候加入以下控制:

<httpProtocol>

<customHeaders>

<add name="Access-Control-Allow-Origin" value="*" />

</customHeaders>

</httpProtocol>

Access-Control-Allow-Origin这个属性配置成*就表示接受任何域过来的请求

2.ajax中请求如下:

$.ajax({

xhrFields: {

withCredentials: true

},

data:{ my: 'a' },

url: 'http://MyApp/Page', 这里是跨域访问

type: 'POST'

})