Input type="email" problem in Chrome

Asked

Viewed 220 times

2

I have a page that loads a contact form via Ajax in a div. It turns out that if I put an invalid character in the email field, Chrome shows me a weird address coming from the field.

For example, if I put dvd@gçmail.com, he shows me this: [email protected] on the console.

I put the ç on purpose because I am doing a validation via Javascript to detect the invalid character.

When I put [email protected] no problem happens. But if I put a ç, Chrome exchanges the gmail.com for xn--gmail-yra.com.

I tried cleaning the cache and nothing. The curious thing is that when I put the focus in the field, an Autofill appears as the image shows:

inserir a descrição da imagem aqui

If I change the type="email" for type="text", the problem does not occur, but I need the input be it type="email".

The input is quite simple:

<input type="email" name="uemail" placeholder="E-mail" style="width: 100%; max-width: 250px; margin: 5px 0;">

Since this only happens in Chrome, someone has some idea of how to fix it?

Edit

I tested in Chome on two different machines and the result was the same.

  • 1

    Check if there is this address in Chrome://Settings/Autofill, then go to Chrome://Settings/clearBrowserData in the Advanced tab, click on "Auto-fill the form data" and send Clear. Also check this link https://support.google.com/chrome/answer/142893?co=GENIE.Platform%3DDesktop&hl=en

  • Dude, you didn’t solve no... Autofill even stopped working, but the same weird email keeps coming, and I already cleaned up the data you indicated. I think I have another site that uses the same thing and never noticed problem... I’ll give a test there...

  • Ixi! Same thing and I had never noticed it... I will test on another pc, may be problem in my Chrome....

  • You use the X-Notifier ? It looks like it might be connected to this...

  • Man, I don’t even know what that is.

  • Vixi then complicated rss, if I see anything on this pass you []’s

  • This is a Chrome problem, see: https://justmarkup.com/log/2015/02/input-type-email-better-dont-use-it/

  • Very strange even, but tb it is strange not to have removed this Autofill by the Chrome Settings... The conclusion of the article is very interesting!

  • I think Autofill doesn’t do any good because it just keeps that little balloon from popping up.

  • 1

    For some time now special characters and accented letters are no longer virtually invalid at Internet addresses. Maybe this is a bug of the implementation of the browser itself on this technology in the display components , and not necessarily a problem...

  • 1

    @Diegorafaelsouza I already found a solution, I will post soon. Thanks!

Show 6 more comments

1 answer

0


I found a solution in this answer Soen. Although the answer is old (2008), it worked like a glove.

I just deleted the excerpt below the function because it does the reverse, so it is not necessary for the case:

this.ToASCII = function ( domain ) {
...
}

The complete code is at the end of the answer.

What you need to do is send it to the function punycode.ToUnicode(domain) just the email domain that comes from input by parameter domain.

For this it is necessary to break the email address to get only the domain. I did so (example):

// considere o email vindo do input como "nome@gçmail.com"
var email = "nome%40xn--gmail-yra.com"; // o %40 representa a arroba @ codificada
var email_array = email.split("%40");
var email_nome = email_array.shift(); // pego o nome no email
var email_dominio = email_array.pop(); // pego o domínio do email

// converte "xn--gmail-yra.com" para "gçmail.com"
var dominio_real = punycode.ToUnicode(email_dominio);

// agora eu junto nome + domínio
var email_real = email_nome+"@"+dominio_real;

This way I can check invalid domain email with Javascript in Chrome.

Code and test:

window.onload = function(){

    // considere o email vindo do input como "nome@gçmail.com"
    var email = "nome%40xn--gmail-yra.com"; // o %40 representa a arroba @ codificada
    var email_array = email.split("%40");
    var email_nome = email_array.shift(); // pego o nome no email
    var email_dominio = email_array.pop(); // pego o domínio do email

    // converte "xn--gmail-yra.com" para "gçmail.com"
    var dominio_real = punycode.ToUnicode(email_dominio);

    // agora eu junto nome + domínio
    var email_real = email_nome+"@"+dominio_real;
    console.log("nome%40xn--gmail-yra.com -> "+email_real);
};

//Javascript Punycode converter derived from example in RFC3492.
//This implementation is created by [email protected] and released into public domain
var punycode = new function Punycode() {
    // This object converts to and from puny-code used in IDN
    //
    // punycode.ToASCII ( domain )
    // 
    // Returns a puny coded representation of "domain".
    // It only converts the part of the domain name that
    // has non ASCII characters. I.e. it dosent matter if
    // you call it with a domain that already is in ASCII.
    //
    // punycode.ToUnicode (domain)
    //
    // Converts a puny-coded domain name to unicode.
    // It only converts the puny-coded parts of the domain name.
    // I.e. it dosent matter if you call it on a string
    // that already has been converted to unicode.
    //
    //
    this.utf16 = {
        // The utf16-class is necessary to convert from javascripts internal character representation to unicode and back.
        decode:function(input){
            var output = [], i=0, len=input.length,value,extra;
            while (i < len) {
                value = input.charCodeAt(i++);
                if ((value & 0xF800) === 0xD800) {
                    extra = input.charCodeAt(i++);
                    if ( ((value & 0xFC00) !== 0xD800) || ((extra & 0xFC00) !== 0xDC00) ) {
                        throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence");
                    }
                    value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000;
                }
                output.push(value);
            }
            return output;
        },
        encode:function(input){
            var output = [], i=0, len=input.length,value;
            while (i < len) {
                value = input[i++];
                if ( (value & 0xF800) === 0xD800 ) {
                    throw new RangeError("UTF-16(encode): Illegal UTF-16 value");
                }
                if (value > 0xFFFF) {
                    value -= 0x10000;
                    output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800));
                    value = 0xDC00 | (value & 0x3FF);
                }
                output.push(String.fromCharCode(value));
            }
            return output.join("");
        }
    }

    //Default parameters
    var initial_n = 0x80;
    var initial_bias = 72;
    var delimiter = "\x2D";
    var base = 36;
    var damp = 700;
    var tmin=1;
    var tmax=26;
    var skew=38;
    var maxint = 0x7FFFFFFF;

    // decode_digit(cp) returns the numeric value of a basic code 
    // point (for use in representing integers) in the range 0 to
    // base-1, or base if cp is does not represent a value.

    function decode_digit(cp) {
        return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 : cp - 97 < 26 ? cp - 97 : base;
    }

    // encode_digit(d,flag) returns the basic code point whose value
    // (when used for representing integers) is d, which needs to be in
    // the range 0 to base-1. The lowercase form is used unless flag is
    // nonzero, in which case the uppercase form is used. The behavior
    // is undefined if flag is nonzero and digit d has no uppercase form. 

    function encode_digit(d, flag) {
        return d + 22 + 75 * (d < 26) - ((flag != 0) << 5);
        //  0..25 map to ASCII a..z or A..Z 
        // 26..35 map to ASCII 0..9
    }
    //** Bias adaptation function **
    function adapt(delta, numpoints, firsttime ) {
        var k;
        delta = firsttime ? Math.floor(delta / damp) : (delta >> 1);
        delta += Math.floor(delta / numpoints);

        for (k = 0; delta > (((base - tmin) * tmax) >> 1); k += base) {
                delta = Math.floor(delta / ( base - tmin ));
        }
        return Math.floor(k + (base - tmin + 1) * delta / (delta + skew));
    }

    // encode_basic(bcp,flag) forces a basic code point to lowercase if flag is zero,
    // uppercase if flag is nonzero, and returns the resulting code point.
    // The code point is unchanged if it is caseless.
    // The behavior is undefined if bcp is not a basic code point.

    function encode_basic(bcp, flag) {
        bcp -= (bcp - 97 < 26) << 5;
        return bcp + ((!flag && (bcp - 65 < 26)) << 5);
    }

    // Main decode
    this.decode=function(input,preserveCase) {
        // Dont use utf16
        var output=[];
        var case_flags=[];
        var input_length = input.length;

        var n, out, i, bias, basic, j, ic, oldi, w, k, digit, t, len;

        // Initialize the state: 

        n = initial_n;
        i = 0;
        bias = initial_bias;

        // Handle the basic code points: Let basic be the number of input code 
        // points before the last delimiter, or 0 if there is none, then
        // copy the first basic code points to the output.

        basic = input.lastIndexOf(delimiter);
        if (basic < 0) basic = 0;

        for (j = 0; j < basic; ++j) {
            if(preserveCase) case_flags[output.length] = ( input.charCodeAt(j) -65 < 26);
            if ( input.charCodeAt(j) >= 0x80) {
                throw new RangeError("Illegal input >= 0x80");
            }
            output.push( input.charCodeAt(j) );
        }

        // Main decoding loop: Start just after the last delimiter if any
        // basic code points were copied; start at the beginning otherwise. 

        for (ic = basic > 0 ? basic + 1 : 0; ic < input_length; ) {

            // ic is the index of the next character to be consumed,

            // Decode a generalized variable-length integer into delta,
            // which gets added to i. The overflow checking is easier
            // if we increase i as we go, then subtract off its starting 
            // value at the end to obtain delta.
            for (oldi = i, w = 1, k = base; ; k += base) {
                    if (ic >= input_length) {
                        throw RangeError ("punycode_bad_input(1)");
                    }
                    digit = decode_digit(input.charCodeAt(ic++));

                    if (digit >= base) {
                        throw RangeError("punycode_bad_input(2)");
                    }
                    if (digit > Math.floor((maxint - i) / w)) {
                        throw RangeError ("punycode_overflow(1)");
                    }
                    i += digit * w;
                    t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
                    if (digit < t) { break; }
                    if (w > Math.floor(maxint / (base - t))) {
                        throw RangeError("punycode_overflow(2)");
                    }
                    w *= (base - t);
            }

            out = output.length + 1;
            bias = adapt(i - oldi, out, oldi === 0);

            // i was supposed to wrap around from out to 0,
            // incrementing n each time, so we'll fix that now: 
            if ( Math.floor(i / out) > maxint - n) {
                throw RangeError("punycode_overflow(3)");
            }
            n += Math.floor( i / out ) ;
            i %= out;

            // Insert n at position i of the output: 
            // Case of last character determines uppercase flag: 
            if (preserveCase) { case_flags.splice(i, 0, input.charCodeAt(ic -1) -65 < 26);}

            output.splice(i, 0, n);
            i++;
        }
        if (preserveCase) {
            for (i = 0, len = output.length; i < len; i++) {
                if (case_flags[i]) {
                    output[i] = (String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0);
                }
            }
        }
        return this.utf16.encode(output);
    };

    //** Main encode function **

    this.encode = function (input,preserveCase) {
        //** Bias adaptation function **

        var n, delta, h, b, bias, j, m, q, k, t, ijv, case_flags;

        if (preserveCase) {
            // Preserve case, step1 of 2: Get a list of the unaltered string
            case_flags = this.utf16.decode(input);
        }
        // Converts the input in UTF-16 to Unicode
        input = this.utf16.decode(input.toLowerCase());

        var input_length = input.length; // Cache the length

        if (preserveCase) {
            // Preserve case, step2 of 2: Modify the list to true/false
            for (j=0; j < input_length; j++) {
                case_flags[j] = input[j] != case_flags[j];
            }
        }

        var output=[];


        // Initialize the state: 
        n = initial_n;
        delta = 0;
        bias = initial_bias;

        // Handle the basic code points: 
        for (j = 0; j < input_length; ++j) {
            if ( input[j] < 0x80) {
                output.push(
                    String.fromCharCode(
                        case_flags ? encode_basic(input[j], case_flags[j]) : input[j]
                    )
                );
            }
        }

        h = b = output.length;

        // h is the number of code points that have been handled, b is the
        // number of basic code points 

        if (b > 0) output.push(delimiter);

        // Main encoding loop: 
        //
        while (h < input_length) {
            // All non-basic code points < n have been
            // handled already. Find the next larger one: 

            for (m = maxint, j = 0; j < input_length; ++j) {
                ijv = input[j];
                if (ijv >= n && ijv < m) m = ijv;
            }

            // Increase delta enough to advance the decoder's
            // <n,i> state to <m,0>, but guard against overflow: 

            if (m - n > Math.floor((maxint - delta) / (h + 1))) {
                throw RangeError("punycode_overflow (1)");
            }
            delta += (m - n) * (h + 1);
            n = m;

            for (j = 0; j < input_length; ++j) {
                ijv = input[j];

                if (ijv < n ) {
                    if (++delta > maxint) return Error("punycode_overflow(2)");
                }

                if (ijv == n) {
                    // Represent delta as a generalized variable-length integer: 
                    for (q = delta, k = base; ; k += base) {
                        t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias;
                        if (q < t) break;
                        output.push( String.fromCharCode(encode_digit(t + (q - t) % (base - t), 0)) );
                        q = Math.floor( (q - t) / (base - t) );
                    }
                    output.push( String.fromCharCode(encode_digit(q, preserveCase && case_flags[j] ? 1:0 )));
                    bias = adapt(delta, h + 1, h == b);
                    delta = 0;
                    ++h;
                }
            }

            ++delta, ++n;
        }
        return output.join("");
    }

    this.ToUnicode = function ( domain ) {

        var domain_array = domain.split(".");
        var out = [];
        for (var i=0; i < domain_array.length; ++i) {
            var s = domain_array[i];
            out.push(
                s.match(/^xn--/) ?
                punycode.decode(s.slice(4)) :
                s
            );
        }
        return out.join(".");
    }
};

Minimized code:

var punycode=new function Punycode(){this.utf16={decode:function(input){var output=[],i=0,len=input.length,value,extra;while(i<len){value=input.charCodeAt(i++);if((value&0xF800)===0xD800){extra=input.charCodeAt(i++);if(((value&0xFC00)!==0xD800)||((extra&0xFC00)!==0xDC00))throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence");value=((value&0x3FF)<<10)+(extra&0x3FF)+0x10000;};output.push(value);} return output;},encode:function(input){var output=[],i=0,len=input.length,value;while(i<len){value=input[i++];if((value&0xF800)===0xD800)throw new RangeError("UTF-16(encode): Illegal UTF-16 value");if(value>0xFFFF){value-=0x10000;output.push(String.fromCharCode(((value>>>10)&0x3FF)|0xD800));value=0xDC00|(value&0x3FF);};output.push(String.fromCharCode(value));};return output.join("");}};var initial_n=0x80,initial_bias=72,delimiter="\x2D",base=36,damp=700,tmin=1,tmax=26,skew=38,maxint=0x7FFFFFFF;function decode_digit(cp){return cp-48<10?cp-22:cp-65<26?cp-65:cp-97<26?cp-97:base;};function encode_digit(d,flag){return d+22+75*(d<26)-((flag!=0)<<5);};function adapt(delta,numpoints,firsttime){var k;delta=firsttime?Math.floor(delta/damp):(delta>>1);delta+=Math.floor(delta/numpoints);for(k=0;delta>(((base-tmin)*tmax)>>1);k+=base){delta=Math.floor(delta/(base-tmin));};return Math.floor(k+(base-tmin+1)*delta/(delta+skew));};function encode_basic(bcp,flag){bcp-=(bcp-97<26)<<5;return bcp+((!flag&&(bcp-65<26))<<5);};this.decode=function(input,preserveCase){var output=[],case_flags=[],input_length=input.length,n,out,i,bias,basic,j,ic,oldi,w,k,digit,t,len;n=initial_n;i=0;bias=initial_bias;basic=input.lastIndexOf(delimiter);if(basic<0)basic=0;for(j=0;j<basic;++j){if(preserveCase)case_flags[output.length]=(input.charCodeAt(j)-65<26);if(input.charCodeAt(j)>=0x80)throw new RangeError("Illegal input >= 0x80");output.push(input.charCodeAt(j));};for(ic=basic>0?basic+1:0;ic<input_length;){for(oldi=i,w=1,k=base;;k+=base){if(ic>=input_length)throw RangeError ("punycode_bad_input(1)");digit=decode_digit(input.charCodeAt(ic++));if(digit>=base)throw RangeError("punycode_bad_input(2)");if(digit>Math.floor((maxint-i)/w))throw RangeError("punycode_overflow(1)");i+=digit*w;t=k<=bias?tmin:k>=bias+tmax?tmax:k-bias;if(digit<t)break;if(w>Math.floor(maxint/(base-t)))throw RangeError("punycode_overflow(2)");w*=(base-t);};out=output.length+1;bias=adapt(i-oldi,out,oldi===0);if(Math.floor(i/out)>maxint-n)throw RangeError("punycode_overflow(3)");n+=Math.floor(i/out);i%=out;if(preserveCase)case_flags.splice(i,0,input.charCodeAt(ic-1)-65<26);output.splice(i,0,n);i++;};if(preserveCase){for(i=0,len=output.length;i<len;i++){if(case_flags[i])output[i]=(String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0);}};return this.utf16.encode(output);};this.encode=function(input,preserveCase){var n,delta,h,b,bias,j,m,q,k,t,ijv,case_flags;if(preserveCase)case_flags=this.utf16.decode(input);input=this.utf16.decode(input.toLowerCase());var input_length=input.length;if(preserveCase)for(j=0;j<input_length;j++){case_flags[j]=input[j]!=case_flags[j];};var output=[];n=initial_n;delta=0;bias=initial_bias;for(j=0;j<input_length;++j){if(input[j]<0x80)output.push(String.fromCharCode(case_flags?encode_basic(input[j],case_flags[j]):input[j]));};h=b=output.length;if(b>0)output.push(delimiter);while(h<input_length){for(m=maxint,j=0;j<input_length;++j){ijv=input[j];if(ijv>=n&&ijv<m)m=ijv;};if(m-n>Math.floor((maxint-delta)/(h+1)))throw RangeError("punycode_overflow (1)");delta+=(m-n)*(h+1);n=m;for(j=0;j<input_length;++j){ijv=input[j];if(ijv<n)if(++delta>maxint) return Error("punycode_overflow(2)");if(ijv==n){for(q=delta,k=base;;k+=base){t=k<=bias?tmin:k>=bias+tmax?tmax:k-bias;if(q<t)break;output.push(String.fromCharCode(encode_digit(t+(q-t)%(base-t),0)));q=Math.floor((q-t)/(base-t));};output.push(String.fromCharCode(encode_digit(q,preserveCase&&case_flags[j]?1:0)));bias=adapt(delta,h+1,h==b);delta=0;++h;}} ++delta,++n;} return output.join("");};this.ToUnicode=function(domain){var domain_array=domain.split("."),out=[];for(var i=0;i<domain_array.length;++i){var s=domain_array[i];out.push(s.match(/^xn--/)?punycode.decode(s.slice(4)):s);}return out.join(".");}}
  • Guy was bad yesterday, until I saw that you had posted the question, but my bride had just arrived and I could not even see the question right, then when I went to see you had already erased... I hope you’ve already solved, whatever I can help you give me a touch later. []s

  • 1

    Quiet, I managed to resolve. It was incompatibility with jQuery. Safari, both desktop and iPhone iOS 6 (same old) do not accept . append() or . html() from jQuery. I solved using same pure JS.

  • Take a look at the code of this my answer and tell me why it doesn’t work in the AP application. https://answall.com/questions/293265/como-salvar-objetos-javascript-no-formato-json-na-localstorage-e-depois-desseri/293275#293275

  • @Leocaracciolo apparently has no reason not to work. This AP is a bit crazy. It is asking a lot of question with the same thing and does not solve anything.

  • Blz, I tried console.log and I will check and it does not appear there in the browser console. The other answer appears. How do I appear on the console? edits there.

  • What do you mean? I tested it here and it appears on the normal console.

  • Tonces my chrome bugged.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.