Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chrome background script 实现跨域请求数据 #71

Open
chenxiaochun opened this issue May 26, 2020 · 0 comments
Open

Chrome background script 实现跨域请求数据 #71

chenxiaochun opened this issue May 26, 2020 · 0 comments

Comments

@chenxiaochun
Copy link
Owner

chenxiaochun commented May 26, 2020

事情背景

最近开发一个 Chorme 插件,需要在https://item.jd.com上发起请求加载我们系统中的一个接口数据。一开始我是直接在页面中发起fetch请求,立刻就遇到了两个问题。

第一个问题是https://item.jd.com使用的是https协议。而我们的系统因为只能在内网访问,所以只是http协议的网站。当在页面中直接发起fetch请求时,浏览器会认为它不是一个安全的请求,会直接给你 block 掉:

Mixed Content: The page at 'https://item.jd.com/100011503930.html' was loaded over HTTPS, but requested an insecure resource 'http://hdj.jd.com/api/test'. This request has been blocked; the content must be served over HTTPS.

第二是即使解决了访问协议不同问题,依然不可能会从我们系统中拿到数据。因为还会有跨域的问题。

解决办法

后来改用在浏览器插件对应的content.js中使用chrome.extension.sendRequest发起请求,此函数支持两个参数:

  • 第一个参数是一个自定义对象,在这里我定义了两个属性:

title,用来表示发起的请求类型
api,是需要实际获取数据的 api 接口

  • 第二个参数是一个回调函数,稍后用来接收从background.js中返回的数据
chrome.extension.sendRequest({ title: 'getData', api: 'http://hdj.jd.com/getData.json' }, (resData: any) => {
  console.log(resData)
})

background.js中使用chrome.extension.onRequest.addListener监听发起的请求。它接受一个回调函数,其中第一个回调参数message就是上面的sendRequest传递进来的参数值

从它里面取出title值,用来判断是不是需要发起的请求

chrome.extension.onRequest.addListener((message, sender, sendResponse) => {
  if (message.title === 'getData') {
    fetch(message.api)
      .then((response) => {
        return response.json()
      })
      .then((data) => {
        sendResponse(data)
      })
  }
})

然后在background.js中正常发起fetch请求。将拿到的数据使用回调函数的第三个参数sendResponse返回到content.js中,也就能拿到数据了:

sendResponse(data)

这里要注意:在background.js中使用console.log打印的信息,是不会显示在当前页面的控制台中。你需要打开浏览器的扩展,点击”background page“打开一个独立的控制台,就能看到它的打印信息了

image

结语

这种方法理论上绕过了任何跨域限制,可以实现在任意网站中去请求另一个网站的数据(当然,前提是得有权限)。但是,如果要将插件发布到 Chrome AppStore 上,是否能过审,个人就不清楚了😂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant