Andris Reinman

More info and contact - about.me/andrisreinman
  • rss
  • archive
  • Atribuudid ja omadused HTML elementidel

    JavaScriptis HTML elementidega majandades tuleb meeles pidada, et igal elemendil on olemas korraga kahte tüüpi andmevälju, milleks on omadused ja atribuudid. Osaliselt need ka kattuvad, näiteks A elemendi omadus href on samaaegselt elemendi atribuudi href alias, seega muutes üht, muutub kohe ka teine. Suurema osa väljade puhul see siiski nii ei ole - ühel elemendil võivad korraga olla sama nime, kuid erineva väärtusega omadused ning atribuudid.

    Omadused ja atribuudid Chrome Developer Toolsis

    Pildilt on näha, et samal SPAN elemendil on korraga erineva väärtusega omadus ja atribuut atribuut1.

    Omadused

    Omadus on elemendi kui objekti omadus, mida saab seada ning lugeda täpselt samamoodi nagu iga teise JavaScripti objekti korral. Omaduse väärtuseks võib olla suvaline JavaScripti väärtus, selleks võib olla näiteks viide mõne teise objekti juurde või hoopis funktsioon.

    var elm = document.createElement("span");
    
    // Omaduse seadmine
    elm.omadusString = "väärtus";
    elm.omadusNumber = 12345;
    elm.omadusObjekt = {key: "value"};
    elm.omadusFunktsioon = function(i){return i + 1;};
    elm["omadus" + "Element"] = document.createElement("div");
    
    // Omaduse lugemine
    alert(elm.omadusFunktsioon(10)); // 11
    alert(elm.omadusElement.outerHTML) // <div></div>
    
    // Omaduse kustutamine elemendist
    delete elm.omadusString;
    
    // Omaduse olemasolu kontroll
    "omadusNumber" in elm; // true
    

    Atribuudid

    Atribuut on elemendi, kui HTML sõlme atribuut ning atribuutidega majandamine tähendab HTML puu manipuleerimist brauseri mälus. Erinevalt omadustest ei ole atribuutide nimed tõstutundlikud, seega atribuudi korral on HREF täpselt sama, mis href.

    Vaikimisi saab määrata atribuutide väärtused juba HTML koodis:

    <span id="elm"></span>
    

    Kui nüüd selline element laadida JavaScripti objektiks:

    var elm = document.getElementById("elm");
    

    Siis sellisel juhul on elemendi elm atribuutideks id, mille väärtus on "elm" ning atribuut1, mille väärtuseks on "tekstiline väärtus".

    Juhul kui lisada elemendile uus atribuut või muuta vana väärtust, muudetakse tegelikult brauseri mälus olevat HTML puud.

    elm.setAttribute("atribuut1", "muudetud väärtus");
    elm.setAttribute("atribuut2", "uus väärtus");
    

    Atribuudi muutmist on võimalik kontrollida, kui brausida HTML puud Firebugi või Webkit Developer Tools abil. Samuti on muudatus näha ka innerHTML / outerHTML väärtustes.

    alert(elm.outerHTML); // <span></span>
    

    Atribuudi lugemine

    Atribuuti saab lugeda elemendi meetodiga getProperty(key), kus key on atribuudi nimi. Selle meetodi tagastusväärtuseks on alati kas tekstiväärtus või null, mis tähistab atribuudid puudumist. Muid väärtusi olla ei saa, kuna atribuutide väärtused võivad olla vaid tekstilised. Numbrite puhul tähendab see, et need tuleb seega enne tehetes kasutamist tagasi konverteerida, kasutades Number või parseInt/parseFloat funktsioone.

    alert(elm.getAttribute("atribuut1")); // "muudetud väärtus"
    elm.getAttribute("atribuut3") === null // true
    

    Atribuudi lisamine / muutmine

    Atribuudi väärtuse saab seada meetodiga setAttribute(key, value). Juhul kui sellise võtmega atribuut juba eksisteerib, kirjutatakse see üle, kui aga mitte, luuakse uus. value saab olla ainult tekstiväärtus. Juhul kui väärtuseks on midagi muud, teisendatakse see tekstiliseks toString() meetodiga. Seega tasub arvestada, et näiteks tühjad väärtused (false, undefined, null) esitatakse samuti tekstilisel kujul (nt. "false"), mitte tühja stringina ("").

    elm.setAttribute("atribuut1", "uus väärtus"); // väärtus on "uus väärtus"
    elm.setAttribute("atribuut1", 1234); // väärtus on "1234"
    elm.setAttribute("atribuut1", false); // väärtus on "false"
    elm.setAttribute("atribuut1"); // väärtus on "undefined"
    elm.setAttribute("atribuut1", {key: "value"}); // väärtus on "[object Object]"
    

    Atribuudi olemasolu kontrollimine

    Atribuudi eksisteerimist saab kontrollida meetodiga hasAttribute(key). Alternatiivselt saab atribuudi olemasolu kontrollida, kui vaadata kas selle väärtus on null või mitte.

    elm.hasAttribute("atribuut1"); // true
    elm.hasAttribute("atribuut3"); // false
    elm.getAttribute("atribuut1") !== null; // true
    elm.getAttribute("atribuut3") !== null; // false
    

    Tasub tähele panna, et kui omadust sab kontrollida "key" in elm konstruktsiooniga, siis atribuutide korral in operaator ei ütle midagi kasulikku, sellisel viisil atribuudi olemasolu kontrollida ei saa.

    Atribuudi kustutamine

    Atribuudi kusutamine võib olla muu hulgas oluline, kui soovitakse lahti saada elemendi id atribuudist - näiteks on see element saadud kloonimise tagajärjel ja omab seega sama sama väärtusega id atribuuti, nagu originaalne objektgi ja võib seega konflikte tekitada.

    Atribuudi väärtuse üle kirjutamine tühja stringi või - veel vähem - tühise väärtusega nagu false või undefined, ei kustuta seda atribuuti. Atribuut tuleb kustutada meetodiga removeAttribute.

    elm.removeAttribute("atribuut2");
    alert(elm.hasAttribute("atribuut2")); // false
    

    Aliased

    Osad erilised omadused on sama nimega atribuutide aliased. Üldiselt on nendeks vormielementide value väärtused, linkide href jne. Oluline on siinkohal see, et just omadus on atribuudi alias, mitte vastupidi - kui tavaliselt saab omaduse väärtus olla suvaline väärtus, siis taoliste aliaste puhul konverteeritakse väärtus stringiks.

    Samas on ka aliaste korral erisusi. Näiteks checkbox elemendi checked omadus, mis on seotud checked atribuudiga ainult lehe laadimisel - hiljem võivad atribuudi ja omaduse väärtused erineda, aga seda kas checkbox on linnukesega või mitte, määrab juba omadus, mitte atribuut. Kusjuures omadus hakkab määrama linnukese olekut alles siis, kui omaduse muutmine muudab ka linnukese olekut.

    Kokkuvõtteks

    Omaduste ja atribuutide puhul tuleb eelkõige vahet teha selles, et atribuudi korral muudetakse HTML elementi, aga omaduse puhul JavaScripti objekti. Üldiselt on tegu täiesti erinevate asjadega, mis võivad ka samade võtme nimedega eksisteerida koos, va. siis mõned erijuhud, kus tuleb arvestada aliastega.

    • 1 week ago
    • 2 notes
    • #html
    • #javascript
    • #properties
    • #attributes
    2 Comments
  • Sending E-Mail messages from Node.js

    NB This article was originally published at Node Knockout blog

    tl;dr — How to send an e-mail using Nodemailer

    Install Nodemailer

    > npm install nodemailer
    

    Include the module in your script and create a reusable transport object

    var nodemailer = require("nodemailer");
    
    var smtpTransport = nodemailer.createTransport("SMTP",{
       service: "Gmail",
       auth: {
           user: "gmail.user@gmail.com",
           pass: "gmailpass"
       }
    });
    

    Send an e-mail using the connection object

    smtpTransport.sendMail({
       from: "My Name <me@example.com>", // sender address
       to: "Your Name <you@example.com>", // comma separated list of receivers
       subject: "Hello ✔", // Subject line
       text: "Hello world ✔" // plaintext body
    }, function(error, response){
       if(error){
           console.log(error);
       }else{
           console.log("Message sent: " + response.message);
       }
    });
    

    Send another e-mail without caring about the outcome (or add the callback function as well, like in the previous code block, if you do care)

    smtpTransport.sendMail({
       from: "My Name <me@example.com>", // sender address
       to: "Your Name <you@example.com>", // comma separated list of receivers
       subject: "Hello ✔", // Subject line
       text: "Hello world ✔" // plaintext body
    });
    

    For additional details see Nodemailer documentation or read through this article.

    Super brief introduction to e-mail technologies

    There are several ways to send an e-mail but in the end it all comes down to the SMTP protocol (Simple Mail Transfer Protocol), since this is the method how e-mails are actually transferred in the interwebs. There have been some other propositions as well in the past, like ISO standardized X.400 for example but these never took off and thus don’t really matter for most.

    The reason why you don’t just open a TCP connection to the recipients incoming SMTP server (the one that is found from the domains DNS MX record and listening on port 25), transmit the message and be done with it, is that in this way, most probably, your message ends up in the junk folder or gets lost entirely - for one, you are not a trusted sender, your sending volumes are way too low (what an irony). This behaviour is also not optimal, as your application would have to handle e-mail bounces, errors, greylisting etc. The better way instead is to turn to your Mail Submission Agent (MSA), which also speaks SMTP and for an exchange of your credentials, happily queues your message for delivery by a relaying Mail Transfer Agent (MTA), which in turn, also speaks SMTP. Often MSA and MTA are one and the same but in theory they are meant to perform somewhat different tasks.

    SMTP is a textual protocol and looks a bit like this:

    CLIENT: <initiates connection to the server>
    SERVER: 220 bob the mailcat listening
    CLIENT: HELO joe.the.sender
    SERVER: 250 Hello, joe.the.sender, nice to meet you!
    CLIENT: MAIL FROM:<me@example.com>
    SERVER: 250 Ok, proceed with recipients
    ...
    

    The numbers returned from the server are status codes, anything equal or above 400 is an error (HTTP anyone?)

    While SMTP defines the transport of the envelope (from the sender’s computer to the recipients inboxes), the contents of the envelope is a completely different thing. Actually the two are so unrelated, you can set whatever you want to as the message contents (you can spoof “from” and “to” addresses in the mail header, you can set a future or prehistoric date for the message, you can use strange byte sequences or use an invalid format etc.) and it still gets delivered. Depending on the MSA, some of the data might be corrected though (eg. the prehistoric date of yours might be adjusted to a more recent value) but not all of it.

    It’s exactly as with regular mail - you have an envelope that says where the letter is supposed end up and then you have the envelope contents that can contain a valid letter, addressed to the same person labeled on the envelope; or some money without an explanation; or some barb wire; or instead a letter addressed someone totally unrelated from the person on the label of the envelope. If you don’t have the envelope you can never be sure just based on the included letter from where the message originates and to whom it was sent.

    Thats why when you look at a spam mail you often see that the recipient name and address fields are blank or invalid - the e-mail client program takes this information from the message contents and not from the envelope. Luckily most servers prepend some of the envelope information also to the mail header, so if you look at the raw source of the message, the first line, “Delivered-To” says which actual address was the final receiver. With several mail accounts ending up in the same e-mail client box, you might not be always able to tell it by yourself. That is also how BCC works - the name is on the envelope but not in the message.

    The most simple e-mail message only consists of header and ascii content

    From: me@example.com
    To: you@example.com
    Subject: Hello
    
    How are you doing?
    

    If you’ve ever done HTTP, then the structure should seem familiar. There’s a header block and after two consecutive line breaks (NB! all line breaks in the interwebs protocols use the form <CR><LF> (eg. the “windows style”) and not the <LF> (the “unix style”) form) comes the body of the message.

    Nontrivial E-mail messages (the ones that want to use non-ascii characters or attachments or almost any other feature) are formatted by MIME which stands for Multipurpose Internet Mail Extensions. You can include multiple “views” of the same data for the message (ie. HTML view and plaintext view), add binary attachments, use different character sets and so on but eventually it is all compiled to a single ascii-only file before it is being sent as the e-mail. The compiled raw source was meant to be human readable on ancient 80 column terminals but with multipart messages (attachments, different “views” etc), it is not a pleasant exercise to browse through - all “extensions” are added on top of the original plain format, making up an onion-like structure. For example one horror child of such extending is the way to support long unicode filenames etc. for attachments (RFC2231) that uses urlencoding instead of mime encoding.

    While most of the strings in e-mail headers are encoded in MIME encoded-word, like the following

    Subject: =?us-ascii?Q?This_is_even_more_***fun***_isn't_it!?=
    

    Then here’s an excerpt from the RFC2231 for splitting long header values:

    Content-Type: application/x-stuff
       title*0*=us-ascii'en'This%20is%20even%20more%20
       title*1*=%2A%2A%2Afun%2A%2A%2A%20
       title*2="isn't it!"
    

    No, it is not fun.

    Y U NO USE SAME ENCODINGS FOR EVERYTHINGZ?

    E-mail modules

    To keep you away from the tedious task of mingling together standard compliant e-mail messages that would go through the wire, enter e-mail sending libraries. There are some for every programming language and for Node.js, there’s Nodemailer by yours truly or emailjs by eleith. These, of course, are not the only options, there used to be (now deprecated) node_mailer by Marak Squires and there still is pony by substack, there’s probably even more but for feature completeness I would definitely suggest using either Nodemailer or emailjs. As the author of Nodemailer I’m not going to describe the other modules but these are still worth checking out.

    Installing Nodemailer

    Installing Nodemailer follows the common path - you can install it from npm. Add a dependency to your package.json and run npm install

    package.json contents:

    ...
    "dependencies": {
       "nodemailer": "0.3.29"
    },
    ...
    

    NB! If you don’t have a package file yet, you can create one automatically by running npm init.

    Now update your installation by running in the same directory the package.json resides.

    npm install
    

    If you are on Windows, you are going to see some error messages flying through while installing but this is normal and doesn’t affect how the module is going to work in the end. Nodemailer tries to drag iconv module to the party as an optional dependency and iconv needs compiling. The iconv module isn’t even used, since all the output and input strings for Nodemailer are always in UTF-8. I just haven’t found a good way to automatically exclude the iconv module since the other modules that share the same codebase (eg. MailParser) do need it.

    And as the last part of the installation equation, include Nodemailer in your script file

    var nodemailer = require("nodemailer");
    

    Selecting mail transport method

    While SMTP makes up the barebones of e-mail messaging, you don’t actually have to use it directly if your MSA accepts something else, for example HTTP POST request with e-mail file etc. Nodemailer includes 3 different mail transports and if this doesn’t suit you, you are welcomed to add your own.

    1. SMTP (obviously)
    2. sendmail to stream message contents to the stdin of sendmail command
    3. SES to post the message contents to Amazon SES REST API endpoint (SES also exposes SMTP endpoint but the used credentials are different in this case, see SES docs for details)

    In this article we only look at using SMTP as it is the most important of them all.

    Setting up SMTP

    To use SMTP you need to have access to a MSA server. If you have a Gmail or Google Apps account, you can use Gmail SMTP for this but you can’t ride it far as there are strict usage limits (about 100 emails per day, unless you have a Google Apps Business account that has higher limits), besides you can only send mail from the same user you are authenticated as, you can’t change it to something else (actually you can change the address but it is displayed as a nasty “via authenticated.user@gmail.com” address, not good for your business if you want it to show just “billing@mycompany.com” instead). If you need to go any further, consider using Sendgrid or Postmark or Mailgun or Amazon SES or any other professional message delivery service. There’s a great discussion in Quora about the reasons behind pricing of these services. If you don’t want to send hundreds of millions messages, it is usually more feasible to pay one of the providers than building your own e-mail infrastructure. But getting started is totally free - you can use Gmail as a starting point and move on to a free trial or a developer account of another service before you need to pay a cent.

    Lets say that for a starters you’re going to use Gmail as the SMTP service. Setting up Nodemailer is a piece of cake in this case, you just need to have your username and password available:

    var smtpTransport = nodemailer.createTransport("SMTP",{
       service: "Gmail",
       auth: {
           user: "gmail.user@gmail.com",
           pass: "gmailpass"
       }
    });
    

    And that’s it, you now have a working wire for transmitting e-mails.

    NB! If your mail configuration needs go beyond Gmail, you can find the full spectre of connection settings from the Nodemailer documentation.

    The problem with SMTP is that you need to have plaintext passwords available somewhere for the app. In case of Gmail there are actually several other options as well. If you use 2 factor authentication, then you can generate application specific password for your mailing app without compromising your real password. There’s also a way to use OAuth1.0 and OAuth2.0 tokens with Gmail if you want to skip using passwords at all. See Nodemailer documentation for details.

    Sending an e-mail

    Now that we have the working wire, we can start sending e-mails. The simplest form of e-mail requires sender address, recipients address, subject line and message text which can be formatted like this:

    var mailOptions = {
       from: "me@example.com", // sender address
       to: "you@example.com", // list of receivers
       subject: "Hello ✔", // Subject line
       text: "Hello world ✔" // plaintext body
    }
    

    If the e-mail structure has been composed, we can send the mail using the “transport wire” defined earlier

    smtpTransport.sendMail(mailOptions, function(error, response){
       if(error){
           console.log(error);
       }else{
           console.log("Message sent: " + response.message);
       }
    });
    

    Nodemailer transport object accepts a large number of messages to be sent at once, you don’t have to wait for the first message to be delivered before you can proceed to the following. Only a limited count of connections are opened to the SMTP server (Nodemailer uses built-in connection pooling) at once and messages are queued automatically for delivery. Thus you can initiate sendMail just as well from a for loop, no need for a complex async setup or a callback hell.

    for(var i=0; i<mailArray.length; i++){
       smtpTransport.sendMail(mailArray[i]);
    }
    

    Address formatting

    Usually you want to include the name of the sender or receiver in addition to the plain address, or sometimes you want to send the e-mail to not just one but several recipients. Nodemailer recipient fields (“to”, “cc”, “bcc”) accept comma separated addresses for multiple recipients and the name can be formatted as well (remeber to enclose the name in double quotes if it contains a comma).

    ...,
    from: "\"Name, User\" <user.name@gmail.com>",
    to: "Receiver Name <receiver@gmail.com>, plain@example.com, \"Name, Another\" <another@gmail.com>"
    ...
    

    And as with any other field, unicode is allowed - you can use non-ascii characters both for the names and for the domains, unicode e-mail domains are converted to the punycode form automatically.

    Advanced options

    Nodemailer supports a lot of advanced options, like DKIM signing or OAuth2.0 token generation and we are not going to cover all of these here, see Nodemailer docs instead for all the details about these features.

    Using HTML and plaintext views

    Usually the e-mail contains either HTML view (usually the default), plain text view or both. It is a good practice to include plaintext view in addition to the HTML view, so the less-able mail clients could fall back. Nodemailer can generate the plaintext view automatically, based on the HTML view but you can create it yourself if you want to (or skip it altogether, as only plaintext capable clients are pretty rare nowadays).

    You can use both html and text views by specifying according properties of the e-mail object.

    ...,
    text: "plaintext contents",
    html: "<p>HTML contents</p>",
    ...
    

    Keep in mind that one of the main differences between text and html views is that newlines are ignored in the html view but not in the plaintext view when rendering the contents.

    You can generate the text view automatically when using generateTextFromHTML property

    ...,
    html: "<p>HTML contents</p>",
    generateTextFromHTML: true,
    ...
    

    Or if you don’t want to include the text contents at all, use only html property

    ...,
    html: "<p>HTML contents</p>",
    ...
    

    Just whatever you do, do not use a plaintext view that only states “Your e-mail client is not capable of displaying this e-mail” - a lot of e-mail clients use the plaintext part (if it exists) as the preview for the message and html part for the actual viewing.

    Adding attachments

    Attachments are defined as an array of attached files. You can use a variety of data sources for the attachments (files on disk, strings, buffers, streams, even web urls) and for these examples we are using files on disk. See Nodemailer documentation for the other options.

    The most simple form of attachments are file paths on disk. Attachment filename and content type are derived automatically in this case (although you can override these values if you want to).

    ...,
    attachments: [
       {filePath: __dirname + "/attachment1.txt"},
       {filePath: __dirname + "/attachment2.txt"}
    ],
    ...
    

    When using images as attachments, you can point to these images as embedded files for the HTML view. You need to define unique cid value for the attachment and use it as an URL.

    ...,
    html: "<p>Embedded image: <img src='cid:image1'/></p>",
    attachments:[
       {filePath: __dirname + "/image1.jpg", cid: "image1"}
    ],
    ...
    

    In conclusion

    Using an e-mail library like Nodemailer makes your life so much easier if you want to send an e-mail with Node.js. Sure, you can compose the message by yourself and transmit it using the standard Node.js net module (and if you’re really interested how the e-mail system works, then this is exactly the way you’re going to do it) but most probably you just need to send an e-mail to your customer and you don’t really care how it is delivered, as long as it makes it through and displays as intended.

    If you want to bring your e-mail related application to the next level, you could also start receiving and parsing e-mail in addition to sending it. For creating your own SMTP MX server for accepting e-mail from the interwebs, you can use simpler SimpleSMTP by yours truly or full featured Haraka by baudehlo which is able to fight against spam as well. If you do not want to manage message exchange server by yourself but to use IMAP for connecting to an existing one, you can use node-imap by mscdex or inbox. Once you have received the e-mail (either through SMTP or IMAP), you can parse the raw source into a structurized object wih MailParser. I have also created a helper module mailuploader to parse an e-mail raw source and post the parsed object to a HTTP address as a regular multipart/form-data upload, so even a PHP script could easily handle it.

    I hope that by reading this article you found out how easy it is to send e-mails using Nodemailer. And if you ever run into trouble with it, then you know where you can file an issue.

    • 6 months ago
    • 2 notes
    • #node.js
    • #smtp
    • #node knockout
    2 Comments
  • test2

    proovin kas veel töötab

    • 1 year ago
    0 Comments
  • StatBot

    Tegin oma statistikamootori mooduli source avalikuks, selle leiab GitHubist. Täpsemalt näiteks kodeeringute statistika skripti leiab näidete kataloogist.

    Tegu on siis node.js skriptiga. Käivitamisel hakkab skript master protsessiks ning tellib vastava arvu forke kes hakkavad siis etteantud aadresse läbi vaatama. Kui feilib (ühendust ei saada, tundmatu nimi, fork lendab õhku vms.) siis saadetakse veateade Kui õnnestub, siis saadetakse lehe kohta metainfo.

    • 1 year ago
    0 Comments
  • Eesti saitide kodeeringud

    Kuna Rene tundis huvi millised kodeeringud hetkel Eesti saitidel aktuaalsed on, lasin oma robotite armee jälle käima ning poolteise tunni pärast oligi veidi üle 60 000 saidi üle kontrollitud. Sisendiks jälle NETI.ee serverite nimekiri. Märkusena tuleb vaid lisada, et eelmine kord oli see nimekiri üsna iganenud, vahepeal nimekiri uuenes ja seekord oli vigade arv (ühendust ei saadud, nimi tundmatu jne) tunduvalt väiksem - 756 viga 61109 saidi kohta.

    Kodeeringute tulemused on aga järgmised:

    Graafik

    TOP 20

    #KODEERINGSAITIDE ARVPROTSENT
    1UTF-83822463.43%
    2ISO-8859-11101218.27%
    3UNKNOWN654810.87%
    4WINDOWS-125714792.45%
    5WINDOWS-12519381.56%
    6ISO-8859-156581.09%
    7ISO-8859-44900.81%
    8WINDOWS-12523720.62%
    9ISO-8859-132610.43%
    12ISO-8859-2480.08%
    13WINDOWS-1250440.07%
    15US-ASCII290.05%
    16KOI8-R240.04%
    18CP1251110.02%
    19ISO-8859-3100.02%
    20UNICODE70.01%
     MUUD1040.17%
     KOKKU60259100.00%
    • 1 year ago
    0 Comments
  • Põnev avastus ligi 5 aastat hiljem

    Kunagi lõi eesti blogi- ja hiljem raamatumaailmas ilma keegi modell Milana. Tegutses ta kusagil Itaalias ning pidas oma tegevuse kohta põnevat blogi “Milana päevik,” mille siis ka raamatuks vormistas. Spekulatsioonide järgi polnud tegu mitte mingi modelli, vaid omapärase viral turunduskampaaniaga Heiti Kenderi poolt.

    Kes iganes aga selle pseudonüümi taga polnud, on nüüdseks selge, et vähemalt osaliselt polnud asjad, nii nagu välja paistsid.

    Nimelt saatis toosama Milana 2007-nda aasta neljandal juulil (tolle päeva sissekanne) Blog.tr.ee klienditeeninduse postkasti kirja, milles teatas oma blogi mitteilmumisest Blog.tr.ee feed’i. Kuna see aadress oli suunatud ka minu postkasti, sattus see ka mulle.

    Nüüd jäi see kiri mulle postkasti arhiivi lapates ette.

    Tol ajal kasutasid Hotmail ja Gmail pettuste vältimiseks sellist meetodit, et lisasid kirja päisesse selle masina IP, millelt kiri välja saadeti (X-Originating-IP). Hiljem see praktika muutus, kuna ilmseltgelt on tegu kasutaja privaatsuse rikkumisega, kuid tollal oli see täiesti tavaline praktika. E-posti klient toda aadressi välja kuidagi ei näidanud, aga kui vaadata “tooret” e-kirja, on see ilusti näha. Ja Milana kirjal on see aadress ka olemas.

    Kiri on saadetud Eestist, Elioni võrgust. Samal päeval, kui mainitud modell väidetavalt Itaalias castingutel käis.

    • 1 year ago
    0 Comments
  • Eesti serverite statistika algandmed

    Kuna mu eelmine postitus eesti serverite teemal tekitas mõningat vastukaja, laadisin kõigile huvilistele andmekaevandamiseks üles statistika algandmed.

    Faili saab alla laadida siit: eesti_serverid.txt.gz (4.9MB, lahtipakitult 42MB)

    Faili formaat on järgmine:

    ---- XXXXX [Wed Dec 28 2011 11:11:14 GMT+0200 (EET)]\n
    {"url":"http://www.server.ee", ....}
    

    Kus XXXXX on number (protsessi id, mis konkreetset aadressi töötles), sellele järgneb aeg millal kirje faili lisati ning järgmisel real on JSON formaadis info aadressi kohta

    JSON formaat

    Juhul kui aadressi laadimisel esines viga, on struktuur järgmine

    url: http://www.server.ee
    error: socket hang up
    

    Juhul, kui leht saadi kätte (hoolimata kas vastuskood oli 200 või 404 vms), on struktuur järgmine

    url: http://www.server.ee # algne url, mille pihta päring tehti
    meta:
        status: 200 # HTTP vastuskood (siin ei tohiks olla 30x, va. eternal loop)
        responseHeaders: # HTTP päringu päise kirjed
            server: Apache # Serveri signatuur
            content-encoding: gzip # vastus on pakitud gzip formaadis (võimalik ka deflate)
            ....
        finalUrl: http://www.server.ee/index2.html # URL milleni välja jõuti, kui oli vaja suunata
        redirectCount: 1 # Mitu suunamist tehti
        cookieJar: # Seatud küpsised (ka võimalikel suunamistel seatud)
            PHPSESSID: # küpsise nimi, väärtuseks massiiv, kuna võib olla mitu sama nimega
                -
                    name: PHPSESSID
                    value: 3fcf34fa436e3170a1aa75238f0d655a
                    path: /
                    _expires: 2011-12-28T09:46:49.138Z
                    _domain: www.server.ee
        charset: ISO-8859-1 # HTML koodis määratud kodeeringu väärtus
        doctype:
            doctype: <!DOCTYPE html> # dokumendi tüübi tekst
            pos: 0 # mitmendast sümbolist hakkab (vanemad IEd ei arvesta kui algab hiljem kui 0)
    

    Reaalne näide

    ---- 31903 [Wed Dec 28 2011 11:53:02 GMT+0200 (EET)]
    {
        "url": "http://tr.ee",
        "meta": {
            "status": 200,
            "responseHeaders": {
                "date": "Wed, 28 Dec 2011 09:53:02 GMT",
                "server": "Apache/2.2.13/DataZone SP 2.0 (Unix) mod_zfpm/0.2",
                "content-encoding": "gzip",
                "expires": "Thu, 19 Nov 1981 08:52:00 GMT",
                "cache-control": "no-store, no-cache, must-revalidate, post-check=0, pre-check=0",
                "pragma": "no-cache",
                "set-cookie": ["VTL=2d1df8f8913cec1537b1fcfdd8998648cdfc29dd; expires=Fri, 27-Dec-2013 09:53:02 GMT; path=/"],
                "x-pingback": "http://blog.tr.ee/rpc/pingback",
                "keep-alive": "timeout=5, max=100",
                "connection": "Keep-Alive",
                "transfer-encoding": "chunked",
                "content-type": "text/html"
            },
            "finalUrl": "http://blog.tr.ee/",
            "redirectCount": 1,
            "cookieJar": {
                "VTL": [{
                    "name": "VTL",
                    "value": "2d1df8f8913cec1537b1fcfdd8998648cdfc29dd",
                    "expires": "2013-12-27T09:53:02.000Z",
                    "path": "/",
                    "_expires": "2013-12-27T09:53:02.000Z",
                    "_domain": "blog.tr.ee"
                }]
            },
            "doctype": {
                "doctype": '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
                "pos": 1
            },
            "charset": "UTF-8"
        }
    }
    

    Näite juures on doctype positsiooniks 1, kui aga vaadata vaadeldud lehe sourcet, tundub et oleks 0. Vahe tuleb sisse sellest, et faili alguses asub unikood sümbol EF BB BF.

    • 1 year ago
    • #web
    • #serverid
    0 Comments
  • Veebilehe kodeeringu määramine

    Kodeeringut saab määrata mitut moodi

    1. -HTTP päises: Content-Type: text/html; charset=UTF-8
    2. -HTML koodis meta http-equiv parameetriga: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    3. -HTML koodis meta charset parameetriga: <meta charset="utf-8" />
    4. -XHTML XML deklaratsioonis: <?xml version="1.0" encoding="utf-8"?>

    Muidu ei olekski midagi, aga tihti kipub olema nii, et kodeering on määratud mitmel eri viisil ning igal kasutatud viisil on määratud erinev kodeering. Üldiselt peaks olema HTTP päises määratud on tähsam kui teised, aga edasi sõltub juba brauserist - näiteks juhul kui XHTML lehel on nii XML deklaratsioon, kui ka meta märgend, eelistab Firefox meta märgendit, aga Chrome XML deklaratsiooni.

    Ja täiendavalt on vähemalt osade Eesti lehtedega puhul, et kõik märgid viitavad nagu oleks tegu näiteks ISO-8859-1 kodeeringuga, tegelikult aga on tekst hoopis Windows-1257. Kõige suurem vahe nende kahe kodeeringu vahel on, et ISO-8859-1 ei toeta š tähte, aga Window-1257 küll. Brauserid suudavad seda mingil ime viisil tuvastada, aga ise HTML koodi töödeldes võib taoline asi osutuda meeletuks peavaluks.

    • 1 year ago
    0 Comments
  • Eesti veebiserverid

    Korjasin kokku Eesti veebiserverite signatuurid ning lõin need kokku üheks tabeliks, mis on näha allolevalt pildilt. Esimeses tulbas on signatuur, teises domeenide arv mis seda signatuuri kasutasid ja kolmandas osakaal.

    Allikaks kasutasin NETI.ee serverite nimekirja. Paraku üsna suur osa (ligi 10%) servereid jäi kättesaamatuks (timeout, tundmatu domeeninimi, ühendusest keelduti jne) ning neid ma ei arvestanud.

    • 1 year ago
    • 20 notes
    • #web
    • #serverid
    • #apache
    20 Comments
  • Array.forEach imedemaa

    Sattusin Twitteris nägema JavaScript: The Definitive Guide autori David flanagani postitust

    And if your browser doesn’t have Array.forEach, use this mind-bender: Array.forEach = Function.prototype.call.bind(Array.prototype.forEach) link

    Ilmnes et tegu on tõesti paraja mind-bender’iga, võttis tükk aega, enne kui suutsin selle rea dešifreerida. Milles siis asi?

    Array.forEach = Function.prototype.call.bind(Array.prototype.forEach);
    

    Antud rida lisab Array objekti uue meetodi forEach, mis käitub järgnevalt

    Array.forEach(array, callback)
    

    array on massiiv või massiivilaadne objekt (näiteks NodeList) ning callback on iteraator, mis saab ükshaaval parameetrina massivi elemendid.

    Kuidas aga suudab rida Function.prototype.call.bind(Array.prototype.forEach) sellise asja tekitada?

    Tuleb välja, et väga lihtsalt.

    Esimene oluline osaline lauses on meetodi bind rakendamine. Antud meetod seob parameetrina saadud väärtuse endast vasakul oleva objekti (milleks hetkel on funktsioon call) kontektsimuutujaga this. Oluline on, et seda konteksti ei ole võimalik enam hiljem üle kirjutada!

    Seega nüüd on meetodi call kontekstiks enam mitte Function.prototype vaid Array.prototype.forEach. Lihtsustatult võib seega sama lause kirjutada nii:

    Array.forEach = Array.prototype.forEach.call
    

    Tavaliselt peaks sellise tehte tulemusena kontekst jälle muutuma. Objekti Array uus meetod peaks selle lause järgi olema sama mis call kuid nüüd oleks kontekstiks juba Array

    Array.forEach = Array.prototype.forEach.call ->  Array.__call__
    

    Kuid see siiski pole nii, sest esimene bind juba sidus konteksti ära (selleks sai Array.prototype.forEach) ning see enam edasistes tehetes ei muutu.

    Kokkuvõttes ongi tulemus selline, et järgmine lause

    Array.forEach(array, callback)
    

    On tegelikult täpselt sama, mis kirjutada

    Array.prototype.forEach.call(array, callback)
    

    Kuid ilmselgelt lühemas ja käepärasemas vormis.

    • 1 year ago
    • 1 notes
    • #javascript
    1 Comments
© 2010–2013 Andris Reinman
Next page
  • Page 1 / 8