草庐IT

php - 简单的 JSONP 和 PHP 示例不起作用

coder 2024-04-30 原文

一直在尝试创建一个简单的 JSONP 调用,但它并不总是有效,我不知道为什么。这是代码:

服务器端(http://server/server.php):

<?php
    $res = json_encode("It works!");

    if(isset($_GET['callback']) === TRUE) {
        header('Content-Type: text/javascript;');
        header('Access-Control-Allow-Origin: http://client');
        header('Access-Control-Max-Age: 3628800');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
        echo $_GET['callback']."(".$res.");";
    } else {
        echo $res;
    }
?>

客户端(http://client/client.html):

<html>
    <head><title>JSONP</title></head>
    <body>
        <h1>JSONP Experiment</h1>
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script>
            function process(data) {
                $('#result').text(data);
            }

            $.getJSON(
                'http://server/server.php?callback=?',
                {'callback': 'process'}
            );

        </script>
        <p id="result"></p>

    </body>
</html>

此代码有效并显示“It works!”在我的

block 中。

  • 为什么当我不使用 {'callback': 'process'} 时它不起作用并将 ?callback=process 直接放入 $.getJSON() URL?

  • 如果我使用 <script src="http://server/server.php?callback=process"></script> 为什么它不起作用而不是 $.getJSON() 调用?

两个不工作的案例实际上都返回了 process("It works");但这没有执行,为什么?

谢谢

最佳答案

这里有两个不同的问题,有不同的答案


使用 $.getJSON() 时它不起作用的原因并将回调的名称直接放在 URL 中是因为 jQuery 的工作方式。

首先让我们看看 jQuery 如何检测到您的 $.getJSON()如果您没有传递任何在设置对象中明确指示它的选项,则调用期望 JSONP - 它 uses这个正则表达式:

/(=)\?(?=&|$)|\?\?/

这明确地寻找 =?在查询字符串或只包含一个 ? 的查询字符串中- 本质上,检测 URL 将返回 JSONP 需要问号。

没有它,jQuery 使用 XHR 发出 Ajax 请求,服务器返回正确的数据。接下来会发生什么取决于同源策略。如果像您显示的代码一样,服务器通过 Access-Control-* 指示允许请求的 header ,数据将可以访问,就像对客户端的原始服务器的 Ajax 请求一样。如果这些 header 不存在,则客户端代码将无法访问返回的数据。

但是,至关重要的是,因为它只是发出一个标准的 Ajax 请求,而不是添加 <script>元素添加到 DOM,这意味着响应文本永远不会被评估为 Javascript 代码 - 这是 JSONP 机制中关键的最后一步。


第二个版本的回答有点棘手,并且根据所提供的信息知道答案是正确的,但是对于上面显示的 HTML 布局,我有理由相信这是原因:您的 HTML 元素定义错误订单。

在页面加载时处理 DOM 时,处理会在每个 <script> 处停止元素,同时同步加载和处理关联的 Javascript。这是为了确保所有 Javascript 都按照预期的顺序执行,并且任何对以特定位置的方式直接修改 DOM 的事物的调用——例如 document.write()。 (你应该永远不要使用,以防你不知道) - 正确地受到尊重。

这样做的结果是,如果您将 <script> DOM 中的元素之前 <p id="result">标记,结果标记实际上并不存在于 process() 所在的位置函数被调用。并且因为您使用了 jQuery 选择器而不是 document.getElementById() , 它吞下了如果您尝试直接修改它会导致的错误。

这就是许多 Javascript 开发人员(包括我自己)现在告诉您应该将 <script> 放在标记为 <body> 中的最后一个元素,因为它提供了可感知的性能改进——尽管实际上加载和处理所有页面资源所花费的网络时间完全相同,但它允许浏览器更快地呈现页面。这样做也不需要使用像 $(document).ready() 这样的东西。/DOMContentLoaded延迟执行的事件(顺便说一句,这也可以解决这个问题,但方式会稍微困惑)。

关于php - 简单的 JSONP 和 PHP 示例不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17991848/

有关php - 简单的 JSONP 和 PHP 示例不起作用的更多相关文章

  1. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  2. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  3. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  4. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  5. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  6. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  7. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  8. ruby - 使用 Ruby,计算 n x m 数组的每一列中有多少个 true 的简单方法是什么? - 2

    给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in

  9. ruby-on-rails - "assigns"在 Ruby on Rails 中有什么作用? - 2

    我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o

  10. Ruby-vips 图像处理库。有什么好的使用示例吗? - 2

    我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby​​代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby​​-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby​​-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby​​-vips的github页面上的链接,我们将不胜感激!如果有ruby​​-

随机推荐