点击启动Mailchimp恶意弹出窗口

11

样式

<link href="//cdn-images.mailchimp.com/embedcode/classic-081711.css" rel="stylesheet" type="text/css">
<style type="text/css">
    #mc_embed_signup{position:absolute; top:0; left:0; width:100%; height:100%; background-color:rgba(0,0,0,.8);display:none;z-index:10000; }
    #mc_embed_signup form{position:fixed; top:10%; left:50%; width:50%; margin-left:-25%; font:normal 100% Helvetica,Arial,sans-serif; font-size:14px; border-radius:4px; border:none; padding:10px 20px; background-color:#fff; color:#000; text-align:left;max-height:400px;overflow-y:auto;overflow-x:hidden;}
    #mc_embed_signup a.mc_embed_close{background:transparent url(http://downloads.mailchimp.com/img/closebox.png) no-repeat; display:block; height:30px; width:30px; text-indent:-999em; position:absolute; top:-10px; right:-10px; display:none; }
    /* Add your own MailChimp form style overrides in your site stylesheet or in this style block.
       We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>

HTML

->

HTML

<div id="mc_embed_signup">
<form action="http://zehava.us3.list-manage2.com/subscribe/post?u=fc807e12a60c9cbaaf5f5616e&amp;id=0707dfe742" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
    <h2>We want to share with you the newest ZEHAVA creations! Leave us your email address! With this occasion, ZEHAVA offers you a gift: a free recondition of your favorite jewelry.</h2>
<div class="indicates-required"><span class="asterisk">*</span> indicates required</div>
<div class="mc-field-group">
    <label for="mce-EMAIL">Email Address  <span class="asterisk">*</span>
</label>
    <input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
</div>
<div class="mc-field-group">
    <label for="mce-FNAME">First Name  <span class="asterisk">*</span>
</label>
    <input type="text" value="" name="FNAME" class="required" id="mce-FNAME">
</div>
<div class="mc-field-group">
    <label for="mce-LNAME">Last Name </label>
    <input type="text" value="" name="LNAME" class="" id="mce-LNAME">
</div>
<a href="#" id="mc_embed_close" class="mc_embed_close">Close</a>    <div id="mce-responses" class="clear">
        <div class="response" id="mce-error-response" style="display:none"></div>
        <div class="response" id="mce-success-response" style="display:none"></div>
    </div>  <div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
</form>
</div>

Javascript

<script type="text/javascript">
var fnames = new Array();var ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';
try {
    var jqueryLoaded=jQuery;
    jqueryLoaded=true;
} catch(err) {
    var jqueryLoaded=false;
}
var head= document.getElementsByTagName('head')[0];
if (!jqueryLoaded) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = '//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js';
    head.appendChild(script);
    if (script.readyState && script.onload!==null){
        script.onreadystatechange= function () {
              if (this.readyState == 'complete') mce_preload_check();
        }    
    }
}

var err_style = '';
try{
    err_style = mc_custom_error_style;
} catch(e){
    err_style = '#mc_embed_signup input.mce_inline_error{border-color:#6B0505;} #mc_embed_signup div.mce_inline_error{margin: 0 0 1em 0; padding: 5px 10px; background-color:#6B0505; font-weight: bold; z-index: 1; color:#fff;}';
}
var head= document.getElementsByTagName('head')[0];
var style= document.createElement('style');
style.type= 'text/css';
if (style.styleSheet) {
  style.styleSheet.cssText = err_style;
} else {
  style.appendChild(document.createTextNode(err_style));
}
head.appendChild(style);
setTimeout('mce_preload_check();', 250);

var mce_preload_checks = 0;
function mce_preload_check(){
    if (mce_preload_checks>40) return;
    mce_preload_checks++;
    try {
        var jqueryLoaded=jQuery;
    } catch(err) {
        setTimeout('mce_preload_check();', 250);
        return;
    }
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://downloads.mailchimp.com/js/jquery.form-n-validate.js';
    head.appendChild(script);
    try {
        var validatorLoaded=jQuery("#fake-form").validate({});
    } catch(err) {
        setTimeout('mce_preload_check();', 250);
        return;
    }
    mce_init_form();
}
function mce_init_form(){
    jQuery(document).ready( function($) {
      var options = { errorClass: 'mce_inline_error', errorElement: 'div', onkeyup: function(){}, onfocusout:function(){}, onblur:function(){}  };
      var mce_validator = $("#mc-embedded-subscribe-form").validate(options);
      $("#mc-embedded-subscribe-form").unbind('submit');//remove the validator so we can get into beforeSubmit on the ajaxform, which then calls the validator
      options = { url: 'http://mysite.us3.list-manage1.com/subscribe/post-json?u=fcsfse12a6sfsdfsfaf5f5616e&id=0707dfe742&c=?', type: 'GET', dataType: 'json', contentType: "application/json; charset=utf-8",
                    beforeSubmit: function(){
                        $('#mce_tmp_error_msg').remove();
                        $('.datefield','#mc_embed_signup').each(
                            function(){
                                var txt = 'filled';
                                var fields = new Array();
                                var i = 0;
                                $(':text', this).each(
                                    function(){
                                        fields[i] = this;
                                        i++;
                                    });
                                $(':hidden', this).each(
                                    function(){
                                        var bday = false;
                                        if (fields.length == 2){
                                            bday = true;
                                            fields[2] = {'value':1970};//trick birthdays into having years
                                        }
                                        if ( fields[0].value=='MM' && fields[1].value=='DD' && (fields[2].value=='YYYY' || (bday && fields[2].value==1970) ) ){
                                            this.value = '';
                                        } else if ( fields[0].value=='' && fields[1].value=='' && (fields[2].value=='' || (bday && fields[2].value==1970) ) ){
                                            this.value = '';
                                        } else {
                                            if (/\[day\]/.test(fields[0].name)){
                                                this.value = fields[1].value+'/'+fields[0].value+'/'+fields[2].value;                                           
                                            } else {
                                                this.value = fields[0].value+'/'+fields[1].value+'/'+fields[2].value;
                                            }
                                        }
                                    });
                            });
                        $('.phonefield-us','#mc_embed_signup').each(
                            function(){
                                var fields = new Array();
                                var i = 0;
                                $(':text', this).each(
                                    function(){
                                        fields[i] = this;
                                        i++;
                                    });
                                $(':hidden', this).each(
                                    function(){
                                        if ( fields[0].value.length != 3 || fields[1].value.length!=3 || fields[2].value.length!=4 ){
                                            this.value = '';
                                        } else {
                                            this.value = 'filled';
                                        }
                                    });
                            });
                        return mce_validator.form();
                    }, 
                    success: mce_success_cb
                };
      $('#mc-embedded-subscribe-form').ajaxForm(options);

              $('#mc_embed_signup').hide();
        cks = document.cookie.split( ';' );
        var show=true;
        for(i=0;i<cks.length;i++){
            parts = cks[i].split('=');
            if( parts[0].indexOf('MCEvilPopupClosed')!= -1 ) show = false;
        }
        if (show){
            $('#mc_embed_signup a.mc_embed_close').show();
            setTimeout( function(){ $('#mc_embed_signup').fadeIn();} , 2000);
            $('#mc_embed_signup a.mc_embed_close').click(function(){ mcEvilPopupClose();});
        }

        $(document).keydown(function(e){
            if (e == null) { 
              keycode = event.keyCode;
            } else { 
              keycode = e.which;
            }
            if(keycode == 27){
                mcEvilPopupClose();
            }
        });

        function mcEvilPopupClose(){
            $('#mc_embed_signup').hide();
            var now = new Date();
            var expires_date = new Date( now.getTime() + 31536000000 );
            document.cookie = 'MCEvilPopupClosed=yes;expires=' + expires_date.toGMTString()+';path=/';
        }

    });
}
function mce_success_cb(resp){
    $('#mce-success-response').hide();
    $('#mce-error-response').hide();
    if (resp.result=="success"){
        $('#mce-'+resp.result+'-response').show();
        $('#mce-'+resp.result+'-response').html(resp.msg);
        $('#mc-embedded-subscribe-form').each(function(){
            this.reset();
        });
    } else {
        var index = -1;
        var msg;
        try {
            var parts = resp.msg.split(' - ',2);
            if (parts[1]==undefined){
                msg = resp.msg;
            } else {
                i = parseInt(parts[0]);
                if (i.toString() == parts[0]){
                    index = parts[0];
                    msg = parts[1];
                } else {
                    index = -1;
                    msg = resp.msg;
                }
            }
        } catch(e){
            index = -1;
            msg = resp.msg;
        }
        try{
            if (index== -1){
                $('#mce-'+resp.result+'-response').show();
                $('#mce-'+resp.result+'-response').html(msg);            
            } else {
                err_id = 'mce_tmp_error_msg';
                html = '<div id="'+err_id+'" style="'+err_style+'"> '+msg+'</div>';

                var input_id = '#mc_embed_signup';
                var f = $(input_id);
                if (ftypes[index]=='address'){
                    input_id = '#mce-'+fnames[index]+'-addr1';
                    f = $(input_id).parent().parent().get(0);
                } else if (ftypes[index]=='date'){
                    input_id = '#mce-'+fnames[index]+'-month';
                    f = $(input_id).parent().parent().get(0);
                } else {
                    input_id = '#mce-'+fnames[index];
                    f = $().parent(input_id).get(0);
                }
                if (f){
                    $(f).append(html);
                    $(input_id).focus();
                } else {
                    $('#mce-'+resp.result+'-response').show();
                    $('#mce-'+resp.result+'-response').html(msg);
                }
            }
        } catch(e){
            $('#mce-'+resp.result+'-response').show();
            $('#mce-'+resp.result+'-response').html(msg);
        }
    }
}

</script>

弹出框设置为自动启动,用户可以退出。我还想在网站上放置一个链接,以便在命令下显示弹出框。 我已经尝试过:

<a onclick="$('#mc_embed_signup, #mc_embed_signup a.mc_embed_close').css('display', 'block');" href="#">Newsletter</a>

弹出窗口出现了,但似乎不能正常工作。
当我点击链接时,启动这个所谓的恶意弹出窗口的正确方式是什么?

6个回答

18

最近我从客户处获得了这段代码(他们从Mailchimp.com复制而来)

<script type="text/javascript" src="//s3.amazonaws.com/downloads.mailchimp.com/js/signup-forms/popup/embed.js" data-dojo-config="usePlainJson: true, isDebug: false"></script>
<script type="text/javascript">require(["mojo/signup-forms/Loader"], function(L) { L.start({"baseUrl":"mc.us8.list-manage.com","uuid":"a56ce123456bdcb7974e9ea2","lid":"4esdr6bd94"}) })</script>

这是恶意弹出窗口代码,将其添加到您的站点后,当页面加载时会出现弹出窗口(模态窗口),以进行新闻通讯注册。

我的客户希望仅在单击“现在注册”按钮时显示此弹出窗口。这就是我所做的。

首先,我按原样将第一个脚本添加到了网站上:

<script type="text/javascript" src="//s3.amazonaws.com/downloads.mailchimp.com/js/signup-forms/popup/embed.js" data-dojo-config="usePlainJson: true, isDebug: false"></script>

其次,我编写了一个函数来运行第二个脚本中的代码,并将一个点击事件附加到ID为 #open-popup 的按钮上。

  function showMailingPopUp() {
      require(["mojo/signup-forms/Loader"], function(L) { L.start(
  {"baseUrl":"mc.us8.list-manage.com","uuid":"a56ce2128001bdcb7974e9ea2","lid":"1d4c16bd94"}
  ) })
  };

  document.getElementById("open-popup").onclick = function() {showMailingPopUp()};

我原本以为这就是答案,但后来发现 Mailchimp 脚本会在用户第一次关闭弹窗后添加一个名为"MCEvilPopupClosed"的会话 cookie。如果该 cookie 已设置,则无法再次打开弹出窗口(因为此弹出窗口仅在用户进入页面时显示一次)。

解决方法是添加以下代码,在页面加载时删除 cookie,并在每次关闭模态框时删除 cookie(需要 jQuery,但如果您愿意可以使用纯 JavaScript 编写)。编辑: 根据新评论,cookie 键已从 MCEvilPopupClosed 更改为 MCPopupClosed

   jQuery(window).load(function() {
    document.cookie = "MCEvilPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
  });
  jQuery('body').on('click', '.mc-closeModal', function() {
    document.cookie = "MCEvilPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
  });

现在...用户可以随意打开或关闭邪恶的弹窗。

编辑:不要使用我的代码清除Cookie,你可以使用@rok-jaklič提供的解决方案。它比我的更好/更简单。其余部分应该是相同的。


9
只需在showMailingPopUp中添加document.cookie = "MCEvilPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC";,当文档或正文加载时,您就不需要那两个jquery调用。 - rkj
2
谢谢@RokJaklič,只有在添加了您的代码后才对我起作用。 - Nadine
我应该添加什么?我正在尝试实现相同的解决方案。如果你可以编辑答案让它更加简洁,那将非常有帮助。 - hello world
1
@helloworld 你需要在showMailingPopUp()函数中添加MCEvilPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC";。我曾经遇到过路径不同的问题,所以你可能需要在cookie字符串中添加;path=/。 - MarcGuay
4
通过您的解决方案,对我而言Cookie没有被正确设置并且弹窗没有出现,因此我需要像这样添加“路径”参数到Cookie中:document.cookie = "MCEvilPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/"; 值得注意的是,我将弹窗代码添加到域名的根页面之外的页面中。 - Maximillian Laumeister
显示剩余6条评论

6
这只是@LeopoldKristjansson答案的副本,带有@RokJaklič关于集成cookie并使用jQuery绑定点击事件的评论。
JavaScript
<script type="text/javascript" src="//s3.amazonaws.com/downloads.mailchimp.com/js/signup-forms/popup/embed.js" data-dojo-config="usePlainJson: true, isDebug: false"></script>

<script type="text/javascript">

function showMailingPopUp() {
    require(["mojo/signup-forms/Loader"], function(L) { L.start({"baseUrl":"obscured","uuid":"obscured","lid":"obscured"})})
    document.cookie = "MCEvilPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC";                  
};

$(function() {
    $(".open-popup").on('click', function() { 
        showMailingPopUp();
    });
});

</script>

Html

<div class="open-popup">Open evil popup</div>

我尝试了完整的代码,但仍然无法工作。你能帮我吗?在控制台中我得到了这个信息:“因为启用了内容阻止,所以位于“http://mc.us5.list-manage.com/subscribe/form-settings?u=e47e…74a0a8b&c=dojo_request_script_callbacks.dojo_request_script0”的资源被阻止。” - questionbank
@questionbank 这段代码是2016年的 - 我建议您与Mailchimp确认这是否是当前首选方法。在4年内,他们的代码几乎肯定会发生变化,可能会发生重大变化。 - Timothy Lee Russell
我的一个同事在这里问了同样的问题。如果你有时间,请检查一下。https://stackoverflow.com/questions/59607025/how-to-display-the-mailchimp-subscribe-popup-form-on-click - questionbank

4
我需要添加"path=/"以使其在每个页面上都起作用,因为MailChimp将cookie设置为根域。我的网站没有使用jQuery,为了这么小的功能而添加它是不值得的。对我来说,该cookie也不叫MCEvilPopupClosed,而是MCPopupClosed。
放置在Head中。
<script type="text/javascript" src="//s3.amazonaws.com/downloads.mailchimp.com/js/signup-forms/popup/embed.js" data-dojo-config="usePlainJson: true, isDebug: false"></script>
<script type="text/javascript">
function showMailPopup() {
    document.cookie = "MCPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
    document.cookie = "MCPopupSubscribed=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
    require(["mojo/signup-forms/Loader"],function(L){L.start({"baseUrl":"mc.us16.list-manage.com","uuid":"8cb755a469ca9c2a6e87c6502","lid":"b809b6d15b"})});
};
</script>

放置在Body

<button onclick="showMailPopup()">Click</button>

2
我已经添加了删除 MCPopupSubscribed 的代码,这可以防止弹出窗口重复显示。 - ubershmekel

2

确保cookie过期(为了在所有页面上都能正常工作,需要添加路径):

document.cookie = "MCEvilPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";

1
我被迫清除了两个cookie才使其正常工作。
       document.cookie = "MCPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
       document.cookie = "MCPopupSubscribed=; expires=Thu, 01 Jan 1970 00:00:00 UTC";

1
这个方法对我也起作用了,在其他解决方案无法重新打开它之后,谢谢兄弟! - Stephen Kaufman

0

对于其他尝试使用Nuxt/Vue.js(或其他编译时失败的系统)的人,在这里分享一下我的解决方式:

```
  export default {
    mounted() {
      this.setupMailchimpPopup() 
    },
    methods: {
      setupMailchimpPopup () {
        var chimpPopupLoader = document.createElement("script");
        chimpPopupLoader.src = '//s3.amazonaws.com/downloads.mailchimp.com/js/signup-forms/popup/embed.js';
        chimpPopupLoader.setAttribute('data-dojo-config', 'usePlainJson: true, isDebug: false');

        var m = {
          baseUrl: "mc.us19.list-manage.com",
          uuid: "xxx",
          lid: "xxx"
        };
        var s = `
          document.cookie = "MCPopupClosed=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
          document.cookie = "MCPopupSubscribed=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
          require(["mojo/signup-forms/Loader"], function (L) { 
            window._showMailchimpPopup = function() {
              L.start({baseUrl: "${m.baseUrl}", uuid: "${m.uuid}", lid: "${m.lid}"});
            };
          });
        `;
        console.log(s);

        var chimpPopup = document.createElement("script");
        chimpPopup.appendChild(document.createTextNode(s));

        chimpPopupLoader.onload = function() {
          document.body.appendChild(chimpPopup);
        }
        document.body.appendChild(chimpPopupLoader);
      },
```

现在可以通过Vue或其他方式使用window._showMailchimpPopup()打开弹出窗口。除非重新加载页面,否则不会在第二次单击时再次打开。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接