【问题标题】:JSONP communication in a Google Chrome extensionGoogle Chrome 扩展程序中的 JSONP 通信
【发布时间】:2012-01-23 19:52:01
【问题描述】:

我正在编写一个 Google Chrome 扩展程序。我想用 jQuery 使用 jsonp 跨域通信。这是ajax代码:

$.ajax({
    type : 'POST',
    url : $(this).attr('action'),
    data : $(this).serialize(),
    contentType: 'application/json; charset=utf-8',
    dataType : 'jsonp',
    success : function() {
        alert('A');
    }
});

这调用了这个 URL:

http://sgsync.dev.kreatura.hu/api/signup/?callback=jQuery1710883696963544935_1327347078860&nick=&pass=&_=1327347087371

服务器用这个数据回答 200 OK:

jQuery1710883696963544935_1327347078860({"messages":["Minden mez\u0151 kit\u00f6lt\u00e9se k\u00f6telez\u0151!"],"errorCount":1})

之后,我收到以下错误消息:

Can't find variable: jQuery1710883696963544935_1327347078860

我尝试了所有方法,但我无法理解问题所在。请帮帮我!

请注意,我编写了服务器端代码,因此也可能存在问题。

提前致谢!

【问题讨论】:

  • 您是否在content_script 内拨打此电话?
  • JSONP request in chrome extension, callback function doesn't exist? 的可能重复项(这似乎回答了问题)
  • @abraham:是的,我是通过内容脚本进行此调用的。
  • @duskwuff 这正是我的问题。不幸的是,这并不能回答我的问题。我正在为几个网络浏览器(Opera、Safari、Firefox)制作这个扩展,并不是每个浏览器都使用沙盒。我在 Safari 上测试了这段代码,同样的问题。并且 Safari 不使用沙盒。所以必须有办法克服这个问题。

标签: javascript jquery google-chrome-extension jsonp


【解决方案1】:

之所以如此混乱,部分原因是 jQuery API 混淆了 Ajax 调用与 JSONP 调用的问题。当使用$.ajaxdataType: 'jsonp' 时,它不会进行Ajax 调用(不使用XHR 通信),而是使用带有回调的动态脚本注入。这意味着type: 'POST' 将没有任何意义(因为动态脚本注入仅作为 GET 起作用)并且所有data 都将被编码到请求的 URL 中,而不是作为帖子发送身体。如果这确实是为了“发布”数据,则不应使用 JSONP(因为敏感数据将以明文形式发送)。

正如其中一个 cmets 所述,这个问题在此答案中解决,涉及来自 Chrome 内容脚本的 JSONP 请求和使用内容脚本中的 XHR。

JSONP request in chrome extension, callback function doesn't exist?

关于 Chrome 扩展程序,当在 Chrome 扩展程序中使用“内容脚本”时,它们会强制您进入沙盒。您可以从 Chrome 扩展内容脚本中的请求中删除 dataType: 'jsonp',此调用应该可以工作。如果这不起作用,您可以尝试直接使用 XHRHttpRequest 进行调用:

var xhr = new XMLHttpRequest();
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.open("POST", $(this).attr('action'), true);
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
       alert("A");
  }
}
xhr.send($(this).serialize());

关于其他浏览器,我不确定它们的每个特定插件环境如何处理跨域 XHR 调用(或者它们是否一开始就允许它)。这是普通浏览器所不允许的(除非使用 easyXDM 之类的东西)。

【讨论】:

  • 感谢您的回答,我现在意识到了问题所在。我只是简单地将目标站点的 url 添加到权限列表中,现在它可以正常处理常规 AJAX 请求。
【解决方案2】:

看看这个问题和我的回答,因为我认为它可能会给你一个解决方案...
Auto-load bookmarklet when in webpage as a Google Chrome extension

【讨论】:

    【解决方案3】:

    JSON-P 的基本概念:

    插入加载外部 javascript 文件的脚本标签。
    该文件除了使用来自服务器的数据执行一个预定义函数之外什么也不做。

    如何使其工作:

    首先创建一个函数,绑定到全局对象(window)

    window.processMyData = function processMyData(data) {
      console.log(data);
    }
    

    然后在页面中插入一个脚本标签:script = document.createElement("script");

    $('<script></script>')
      .prop({'type': 'text/javascript', 'src': 'http://your.url?with=possible&data=in_it'})
      .appendTo('body');
    

    你看到了吗?不需要 $.ajax 包装器,JSON-P 的工作方式不同。

    祝你好运!

    编辑: 作为对 Duskwuff 的回应,我想补充一点,我并不是说 $.ajax 不好或没用。我不是在这里给你一个 jQuery 代码 sn-p,我试图让你理解你的问题,在更基本的 javascript/html 的帮助下。 JSON-P 不仅仅是加了 P 的 JSON,它与普通的请求完全不同。

    【讨论】:

    • OP 使用 jQuery 的 JSONP 支持寻求帮助,而不是无法处理失败、编码请求、同时“进行中”的多个请求或页面内的多个不同请求的替代品。
    • @duskwuff 我知道,但我想提供见解。在使用 jQuery 之前,最好对问题有一个基本的了解。通过给出这个解释,以及这个更容易理解的例子。
    • 不过,您的“解决方案”无助于解释问题。它或多或少与 jQuery 内部所做的相同。
    • 不是吗?问题是该函数不在全局对象中。我告诉他应该在全局对象中预定义一个函数。我没有解释问题的核心吗?
    • 你让我思考。因此,如果我在全局命名空间上定义一个函数并在 jQuery 请求中传递函数名,那实际上可以工作。至少是不使用沙盒的浏览器。
    猜你喜欢
    • 1970-01-01
    • 2012-09-16
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 2013-12-25
    • 2020-01-17
    相关资源
    最近更新 更多