简体   繁体   English

如何将javascript函数中返回的JSON保存为变量?

[英]How to save JSON returned in a javascript function as a variable?

Im trying to save the client IP address in a variable after retrieving it in JSON form from api.ipify.org. 我试图从api.ipify.org以JSON形式检索客户端IP地址后将其保存在变量中。 I can get the IP to show if I alert the result but cannot get it to save in a variable for some reason. 如果警报结果,但可以显示IP,但由于某种原因而无法将其保存在变量中。

This works: 这有效:

<script>

function getIP(json) {
    alert(json.ip);
}

</script>
<script src="https://api.ipify.org?format=jsonp&callback=getIP"></script>

But this does not work: 但这不起作用:

<script>

var clientIP = ''

function getIP(json) {
    clientIP = json.ip;
    return clientIP;
}

alert(clientIP);

</script>
<script src="https://api.ipify.org?format=jsonp&callback=getIP"></script>

I would like to be able to store the data in a variable so that I can attach it to an embed that will add it into its automated webhook POST. 我希望能够将数据存储在变量中,以便可以将其附加到嵌入中,然后将其添加到其自动Webhook POST中。

<!-- begin video recorder code --><script type="text/javascript">
var IPADDRESSVARIABLE = 'SOME_IP_ADDRESS'
var size = {width:400,height:330};
var flashvars = {qualityurl: "avq/300p.xml",accountHash:"BUNCHOFRANDOMSTUFF", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload: IPADDRESSVARIABLE};
(function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})();
</script>
<div id="hdfvr-content"> </div>
<!-- end video recorder code -->

If I can get the IP address saved as a global variable then I can pass it into the 'payload' key of the 'flash vars'. 如果我可以将IP地址保存为全局变量,则可以将其传递到“闪存变量”的“有效负载”键中。

Your alert won't work because your code is not executing synchronously, getIP doesn't get called until after your alert statement. 您的alert将无法正常工作,因为您的代码未同步执行,直到alert语句之后才调用getIP You need to trigger any functionality that depends on clientIP inside your getIP function. 您需要触发clientIP函数中依赖于clientIPgetIP功能。 Here is an example: 这是一个例子:

 function getIP(json) { var event = new CustomEvent('iploaded', { detail: json.ip }); document.dispatchEvent(event); } document.addEventListener('iploaded', function(event) { var IPADDRESSVARIABLE = event.detail; var size = {width:400,height:330}; var flashvars = {qualityurl: "avq/300p.xml",accountHash:"BUNCHOFRANDOMSTUFF", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload: IPADDRESSVARIABLE}; (function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})(); }); // simulate jsonp callback getIP({ ip: '127.0.0.1' }); 

Also, no need to return in getIP 另外,无需return getIP

The second code example does not work because the variable is only given a value inside of a callback function, which means the alert,which runs synchronously, runs as soon as the javascript interpreter starts reading and running the code line by line, but the getIP function is only called later on when the jsonp request returns a response. 第二个代码示例不起作用,因为仅在回调函数内部为变量提供了一个值,这意味着警报将同步运行,并在javascript解释器开始逐行读取和运行代码时运行,但getIP仅当jsonp请求返回响应时,才调用此函数。 Your first code example was the right way to go. 您的第一个代码示例是正确的方法。

As Rob says, you're expecting the code to run synchronously but that isn't the case. 正如Rob所说,您期望代码能够同步运行,但事实并非如此。

Here's a small edit of your code snippet that will work, basically I've wrapped the alert in a function, I then call that function once the getIP function has finished executing. 这是对您的代码段的一个小修改,它将起作用,基本上,我将警报包装在一个函数中,然后在getIP函数执行完后调用该函数。

<script>

var clientIP = ''

function getIP(json) {
    clientIP = json.ip;
    alertClientIp();
}

function alertClientIp () {
    alert(clientIP);
}

</script>

The code design of the above snippet is a bit nasty, if you only need to use the client IP once, then don't bother storing it as a variable, just pass it to the function which executes you "automated webhook POST" logic. 上面的代码片段的代码设计有点讨厌,如果您只需要使用一次客户端IP,那么就不用理会将其存储为变量,只需将其传递给执行“自动Webhook POST”逻辑的函数即可。

<script>

    function getIP(json) {
        clientIP = json.ip;
        alertClientIp();
    }

    //Accept the client_ip as a param
    function webhookLogic (client_ip) {

       //Execute your logic with the client_ip, 
       //for simplicity I'll stick to your alert.

       alert(client_ip);
    }

    </script>

With regards to your edit 关于您的编辑

It looks like you have the two sets of logic placed in two separate script elements, could you not merge them into one? 看起来您将两组逻辑放置在两个单独的脚本元素中,您无法将它们合并为一个吗?

<script>

    function getIP(json) {
        clientIP = json.ip;
        alertClientIp();
    }

    //Accept the client_ip as a param
    function webhookLogic (client_ip) {

       //Execute your logic with the client_ip, 
       //for simplicity i'll stick to your alert.

       //Trigger your video wrapper code, unsure if 
       //if this method of execution will break your app...
       videoWrapper(client_ip);
    }

     //Your video code from your latest edit
    function videoWrapper (client_ip) {
        var IPADDRESSVARIABLE = client_ip;
        var size = {width:400,height:330};
        var flashvars = {qualityurl: "avq/300p.xml",accountHash:"BUNCHOFRANDOMSTUFF", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload: IPADDRESSVARIABLE};
    (function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})();
   }
    </script>

If that chain of execution breaks your app then I think you need to go back to the drawing board with regards to the composition of your question, it's clear what you want to do but your question lacks a bit of meta-data as to how this logic all "fits together". 如果执行链中断了您的应用程序,那么我认为您需要回过头来考虑问题的构成,很清楚您想做什么,但是您的问题缺少有关此操作的元数据逻辑所有“适合”。

Try this : 尝试这个 :

 function getIP(json) { return json.ip; } var json = { "ip": "111.22.33.44"} var clientIP = getIP(json); alert(clientIP); 

I found a workaround! 我找到了解决方法! I stored the result of the IP function into a hidden div to act as a container. 我将IP函数的结果存储到一个隐藏的div中以充当容器。 I then declared a variable inside the embed code and set it to the innerHMTL. 然后,我在嵌入代码中声明了一个变量,并将其设置为innerHMTL。 It may not be the most elegant but it does exactly what I want it to! 它可能不是最优雅的,但确实可以满足我的要求!

//hidden container to store the client IP address
<div id = 'ipContainer' style='display:none'></div>

//function to retrieve the client IP address
<script>
function getIP(json) {
    document.getElementById('ipContainer').innerHTML = json.ip;
}
</script>

//shortened version of the URL that returns the IP
<script src='http://www.api.ipify.org'><script>


//embed code for the video recorder
<script>
<!-- begin video recorder code --><script type="text/javascript">
var clientIP = document.getElementById('ipContainer').innerHTML;
var size = {width:400,height:330};


//I passed the clientIP variable into the payload element of the flashvars object
var flashvars = {qualityurl: "avq/300p.xml",accountHash:"RANDOM ACCOUNT HASH", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload:clientIP}; //Here i passed the clientIP which is nor stored as a variable
(function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})();
</script>
<div id="hdfvr-content"> </div>
<!-- end video recorder code -->

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM