Karakter aman untuk url ramah [ditutup]

168

Saya perlu membuat situs web yang akan memiliki artikel, dan saya ingin membuat URL yang ramah untuknya, misalnya URL halaman dengan

Judul: Tes Artikel

harus menjadi: http://www.example.com/articles/article_test.

Tentu saja saya perlu menghapus beberapa karakter dari judul suka ?atau #, tapi saya tidak yakin yang mana yang harus dihapus.

Bisakah seseorang memberi tahu saya karakter apa yang aman untuk disimpan?

Paulo
sumber
Ada pertanyaan serupa, di sini . Lihat itu, Anda mungkin menemukan beberapa jawaban yang berguna di sana juga (ada cukup banyak dari mereka).
Benteng

Jawaban:

210

Mengutip bagian 2.3 dari RFC 3986 :

"Karakter yang diizinkan dalam URI tetapi tidak memiliki tujuan khusus disebut tidak terpelihara. Ini termasuk huruf besar dan kecil, angka desimal, tanda hubung, titik, garis bawah, dan tilde."

ALPHA  DIGIT  "-" / "." / "_" / "~"

Perhatikan bahwa RFC 3986 mencantumkan lebih sedikit tanda baca yang dipesan daripada RFC 2396 yang lebih lama .

Lewati Kepala
sumber
@ Skip Head, apakah "karakter" termasuk karakter yang disandikan seperti çdan õ?
Mohamad
6
@Mohamad: Tidak, ASCII saja, meskipun dukungan UTF-8 semakin baik.
Dietrich Epp
@Dietrich Epp, terima kasih. Saya kira seharusnya tidak masalah jika URL itu untuk keperluan dekorasi dan SEO, seperti: www.mysite.com/[postId[/post-title-with-ç-and-õ
Mohamad
1
@Mohamad: Bagian terakhir di sana akan diubah di bawah kap post-title-with-%C3%A7-and-%C3%B5, tetapi tetap akan ditampilkan di bilah lokasi pengguna sebagai post-title-with-ç-and-õ.
Dietrich Epp
7
Pembaca Anda adalah Portugis, jadi gunakan karakter Portugis.
Dietrich Epp
107

Ada dua set karakter yang perlu Anda perhatikan: dicadangkan dan tidak aman .

The dilindungi undang-undang karakter:

  • simbol untuk 'dan ("&")
  • dolar ("$")
  • tanda tambah ("+")
  • koma (",")
  • forward slash ("/")
  • usus besar (":")
  • semi-colon (";")
  • sama dengan ("=")
  • tanda tanya ("?")
  • Simbol 'At' ("@")
  • pound ("#").

Karakter yang umumnya dianggap tidak aman adalah:

  • ruang ("")
  • kurang dari dan lebih besar dari ("<>")
  • buka dan tutup kurung ("[]")
  • buka dan tutup kawat gigi ("{}")
  • pipa ("|")
  • garis miring terbalik ("\")
  • tanda sisipan ("^")
  • persen ("%")

Saya mungkin lupa satu atau lebih, yang mengarah pada saya untuk menggemakan jawaban Carl V. Dalam jangka panjang Anda mungkin lebih baik menggunakan "daftar putih" karakter yang diizinkan dan kemudian meng-encode string daripada mencoba untuk tetap mengikuti karakter yang dilarang oleh server dan sistem.

Gary. Ray
sumber
#adalah karakter khusus yang digunakan untuk bookmark pada halaman tertentu, dibuat dengan memiliki satu elemen HTML dengan atribut nama yang cocok atau atribut-id (sans- #simbol).
TheLonelyGhost
Terima kasih - Saya telah memperbarui jawabannya.
Gary. Ray
Tanda tanya muncul di sini sebagai cadangan dan tidak aman - Saya menganggapnya sebagai cadangan saja, tapi saya mungkin salah
Jonathan Basile
6
Lainnya tampaknya tidak setuju bahwa tilde ~itu tidak aman. Apakah Anda yakin begitu?
drs
3
Daftar putih tidak begitu baik jika menangani bahasa selain bahasa Inggris. Unicode hanya memiliki terlalu banyak poin kode OK. Oleh karena itu, memasukkan daftar hitam yang tidak aman cenderung menjadi yang paling mudah diterapkan dalam ekspresi reguler.
Patanjali
41

Anda sebaiknya hanya menyimpan beberapa karakter (daftar putih) daripada menghapus karakter tertentu (daftar hitam).

Anda dapat mengizinkan karakter apa pun secara teknis, selama Anda menyandikannya dengan benar. Tetapi, untuk menjawab dengan semangat pertanyaan, Anda harus mengizinkan karakter ini:

  1. Huruf kecil (konversi huruf besar menjadi huruf kecil)
  2. Bilangan, 0 hingga 9
  3. Tanda hubung - atau garis bawah _
  4. Tilde ~

Segala sesuatu yang lain memiliki makna yang berpotensi khusus. Misalnya, Anda mungkin berpikir Anda dapat menggunakan +, tetapi dapat diganti dengan spasi. & Juga berbahaya, terutama jika menggunakan beberapa aturan penulisan ulang.

Seperti komentar lainnya, lihat standar dan spesifikasi untuk detail lengkap.

carl
sumber
15
Suatu preiod, yang saya temukan hari ini, adalah pilihan karakter yang buruk untuk digunakan untuk encoder Base64 URL-safe, karena akan ada kasus-kasus langka di mana data Anda yang dikodekan dapat menghasilkan dua titik berturut-turut (".."), yang penting dalam bahwa itu merujuk ke direktori induk.
pohl
5
@pohl: itu hanya masalah jika URL Anda digunakan sebagai jalur file, baik dalam kode Anda atau jika server web Anda benar-benar mencoba untuk memetakan URL ke file sebelum meneruskan permintaan ke skrip (sayangnya sangat umum).
André Caron
4
Sebenarnya, dalam kasus kami menggunakannya sebagai jalur file akan baik-baik saja, karena dalam file unix diizinkan untuk memiliki beberapa, dan bahkan berturut-turut, titik-titik dalam nama mereka. Bagi kami, masalah muncul dalam alat pemantauan yang disebut Lingkup Situs yang memiliki bug (mungkin regex naif) dan melaporkan downtime palsu palsu. Bagi kami, kami terjebak pada versi lama Cakupan Situs, tim admin menolak untuk membayar pemutakhiran, dan satu klien yang sangat penting memiliki Cakupan Situs (bukan yang setara) yang tertulis dalam kontrak mereka. Memang, sebagian besar tidak akan menemukan diri mereka pada posisi saya.
pohl
8
Terima kasih Tuhan bahwa seseorang memposting daftar tanpa banyak mengoceh. Adapun dot (.) - seperti yang dikatakan @pohl, jangan gunakan itu! Berikut ini adalah kasus aneh lain di IIS (tidak tahu apakah ini terjadi di Server Web lain): jika di akhir URL Anda kemungkinan besar Anda akan mendapatkan 404 kesalahan (itu akan mencoba untuk mencari [/ pagename] . halaman)
nikib3ro
34

Selalu Aman

Ini aman (dalam teori / spec), pada dasarnya di mana saja kecuali nama domain.
Persen-enkode apa pun yang tidak terdaftar, dan Anda siap melakukannya.

    A-Z a-z 0-9 - . _ ~ ( ) ' ! * : @ , ;

Terkadang Aman

Hanya aman bila digunakan dalam komponen URL tertentu; gunakan dengan hati-hati.

    Paths:     + & =
    Queries:   ? /
    Fragments: ? / # + & =
    

Tidak pernah aman

Menurut spesifikasi URI (RFC 3986), semua karakter lain harus dikodekan persen. Ini termasuk:

    <space> <control-characters> <extended-ascii> <unicode>
    % < > [ ] { } | \ ^
    

Jika kompatibilitas maksimum menjadi perhatian, batasi rangkaian karakter ke AZ az 0-9 - _.
(dengan periode hanya untuk ekstensi nama file).

Simpan Konteks dalam Pikiran

Meskipun valid per spec, URL masih bisa "tidak aman", tergantung pada konteksnya. Seperti file: /// URL yang berisi karakter nama file tidak valid, atau komponen permintaan yang mengandung "?", "=", Dan "&" saat tidak digunakan sebagai pembatas. Penanganan yang benar untuk kasus-kasus ini umumnya tergantung pada skrip Anda dan dapat diselesaikan, tetapi ini sesuatu yang perlu diingat.

Beejor
sumber
Bisakah Anda memberikan sumber apa pun untuk klaim kedua Anda ("Terkadang Aman")? Secara khusus, saya percaya Anda salah mengatakan bahwa =itu tidak aman untuk pertanyaan. Misalnya, FIQL menerima tanda sama dan menggambarkan dirinya sebagai "URI-friendly" dan "dioptimalkan dan dimaksudkan untuk digunakan dalam komponen permintaan". Dalam interpretasi saya, RFC 3986 secara eksplisit memungkinkan "=", "&", "+" dan lainnya dalam kueri.
DanielM
@DanielM "?", "=", Dan "&" valid dalam kueri per spec, meskipun dalam praktiknya mereka banyak digunakan untuk mem-parsing pasangan nilai-nama dalam kueri. Jadi mereka bisa tidak aman sebagai bagian dari nama / nilai itu sendiri. Apakah ini merupakan "tidak aman" atau tidak mungkin menjadi masalah pendapat.
Beejor
Beberapa sumber, seperti yang diminta. (1) RFC 3986, Sec 3.4: "[...] komponen permintaan sering digunakan untuk membawa informasi pengidentifikasian dalam bentuk pasangan 'key = value' [...]" (2) Spec URL WhatWG, Sec. 6.2: "Membangun dan mengencangkan objek URLSearchParams cukup mudah: [...] params.toString() // "key=730d67"" (3) Manual PHP, http-build-query: "Hasilkan string kueri yang disandikan URL. [...] Contoh di atas akan menampilkan: 0=foo&1=bar[...]"(4) J. Starr, Perishable Press:" Saat membuat halaman web, sering kali perlu menambahkan tautan yang memerlukan string kueri parameterisasi. "
Beejor
@Beejor: Saya membuat URL & saya menggunakan '-' dan ';' selama konstruksi. Ini bukan aplikasi web tetapi aplikasi seluler. Bukan pengembang web & karenanya, apakah saya akan aman jika saya menggunakan dua karakter di atas di properti Path? docs.microsoft.com/en-us/dotnet/api/…
karsnen
1
@karsnen Itu adalah karakter URL yang valid. Meskipun jika digunakan untuk mereferensikan path pada sistem file lokal, perlu diingat bahwa beberapa sistem tidak mengizinkan karakter tertentu dalam nama file. Misalnya, "file: /// path / to / my: file.ext" tidak valid di Mac.
Beejor
17

Melihat RFC3986 - Uniform Resource Identifier (URI): Sintaks Generik , pertanyaan Anda berputar di sekitar komponen jalur URI.

    foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
      |   _____________________|__
     / \ /                        \
     urn:example:animal:ferret:nose

Mengutip bagian 3.3, karakter yang valid untuk URI segmentadalah tipe pchar:

pchar = tidak diawetkan / pct-encoded / sub-delims / ":" / "@"

Yang terurai menjadi:

ALPHA / DIGIT / "-" / "." / "_" / "~"

pct-encoded

"!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

":" / "@"

Atau dengan kata lain: Anda dapat menggunakan (non-kontrol-) karakter dari tabel ASCII , kecuali / , ?, #, [dan ].

Pemahaman ini didukung oleh RFC1738 - Uniform Resource Locators (URL) .

Philzen
sumber
2
Ini adalah contoh yang bagus dari jawaban yang benar secara teoritis, yang mengarah ke masalah ketika diterapkan pada dunia nyata tempat kita hidup. Memang benar bahwa sebagian besar karakter itu tidak akan menyebabkan masalah sebagian besar waktu. Tetapi ada di dunia nyata hal-hal seperti proxy, router, gateway, relay, dll, yang semuanya "suka" untuk memeriksa dan berinteraksi dengan URL dengan cara yang mengabaikan standar teoritis. Untuk menghindari jebakan-jebakan ini, Anda cukup terbatas untuk melarikan diri dari segala hal kecuali alfanumerik, tanda hubung, garis bawah, dan titik.
deltamind106
1
@ deltamind106 Dapatkah Anda memberikan contoh dan / atau referensi untuk mengklarifikasi karakter mana yang aman menurut RFC yang sebenarnya tidak? Saya lebih suka tetap berpegang pada fakta yang didukung oleh standar dalam jawaban saya, dan saya senang memperbarui jawaban saya jika Anda dapat menunjukkan fakta yang mungkin saya abaikan.
Philzen
2
@ deltamind106 Saya sarankan kita mencoba untuk mendapatkan produk untuk mengikuti standar daripada mengatakan kepada devs untuk tidak melakukannya. Saya menganggap peringatan Anda pantas, tetapi kami harus melakukan bagian kami dalam melaporkan ketidakpatuhan kepada vendor jika perlu.
Lo-Tan
@ Pilzen: Saya membuat URL & saya menggunakan '-' dan ';' selama konstruksi. Ini bukan aplikasi web tetapi aplikasi seluler. Bukan pengembang web & karenanya, apakah saya akan aman jika saya menggunakan dua karakter di atas di properti Path? docs.microsoft.com/en-us/dotnet/api/…
karsnen
1
@ karsnen Ya tentu saja -dan ;aman, itulah jawaban saya dan RFC jelas menyatakan.
Philzen
12

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

LKK
sumber
3
Bukankah "ALPHA" menyiratkan "DIGIT"? Saya berasumsi ALPHA adalah kependekan dari "alfanumerik", dan alfanumerik berarti huruf besar, huruf kecil dan angka.
Luc
11
Sebenarnya alpha tidak menyiratkan alfanumerik. Alfa dan numerik adalah 2 hal yang berbeda dan alfanumerik adalah kombinasi dari hal-hal itu. Dia bisa menulis jawabannya seperti ini: ALPHANUMERIC / "-" / "." / "_" / "~"
MacroMan
1
Notasi ABNF untuk 'tanpa pagu harga' dalam RFC 3986 mencantumkannya secara terpisah.
Patanjali
11

Dari konteks yang Anda gambarkan, saya menduga bahwa apa yang sebenarnya Anda coba buat adalah sesuatu yang disebut 'SEO slug'. Praktik umum yang paling dikenal untuk mereka adalah:

  1. Konversikan ke huruf kecil
  2. Ubah seluruh urutan karakter selain az dan 0-9 menjadi satu tanda hubung (-) (bukan garis bawah)
  3. Hapus 'stop words' dari URL, yaitu kata-kata yang tidak dapat diindeks bermakna seperti 'a', 'an', dan 'the'; Google 'kata berhenti' untuk daftar lengkap

Jadi, sebagai contoh, sebuah artikel berjudul "Penggunaan! @% $ * Untuk Mewakili Komik Bersumpah" akan mendapatkan seonggok "penggunaan-mewakili-sumpah-komik".

kekacauan
sumber
Apakah ini benar-benar pendekatan yang baik untuk menghapus "kata-kata henti" ini dari url? Apakah mesin pencari akan menghukum situs web karena ini?
Paulo
Mesin pencari umumnya diyakini hanya mengakui sebagian URL dan / atau memberikan pengurangan signifikansi untuk porsi selanjutnya, jadi dengan menghapus kata-kata berhenti, apa yang Anda lakukan adalah memaksimalkan jumlah kata kunci yang Anda tanamkan di URL yang Anda punya peluang. sebenarnya peringkat.
chaos
1
@chaos Apakah Anda masih merekomendasikan pengupasan StopWord, jika Anda mempertimbangkan ini: seobythesea.com/2008/08/google-stopword-patent Juga, dapatkah Anda merekomendasikan daftar stopword yang bagus? Ini adalah daftar terbaik yang saya temukan sejauh ini - link-assistant.com/seo-stop-words.html
nikib3ro
@ kape123 Itu sepertinya bukan daftar yang sangat bagus untuk saya. "c" dan "d" adalah bahasa pemrograman, dan banyak dari kata-kata lain itu juga terlihat signifikan. Saya mungkin hanya menghapus yang dasar: a, dan, pada, dari, atau, dengan.
buka
6

Format untuk URI didefinisikan dalam RFC 3986 . Lihat bagian 3.3 untuk detailnya.

Joseph
sumber
6

Dari perspektif SEO, tanda hubung lebih disukai daripada garis bawah. Konversikan menjadi huruf kecil, singkirkan semua apostrof, lalu ganti semua string karakter non-alfanumerik dengan satu tanda hubung. Pangkas tanda hubung yang berlebihan di awal dan akhir.

Mpen
sumber
3

Saya memiliki masalah yang sama, saya ingin memiliki url yang cantik dan sampai pada kesimpulan bahwa saya harus mengizinkan hanya huruf, angka, - dan _ dalam url. Itu baik-baik saja, kemudian saya menulis beberapa regex yang bagus dan saya menyadari bahwa itu mengenali semua karakter UTF8 bukan huruf dalam. Ini tampaknya menjadi masalah yang diketahui untuk mesin .NET regex. JADI saya mendapatkan solusi ini:

private static string GetTitleForUrlDisplay(string title)
{
    if (!string.IsNullOrEmpty(title))
    {
        return Regex.Replace(Regex.Replace(title, @"[^A-Za-z0-9_-]", new MatchEvaluator(CharacterTester)).Replace(' ', '-').TrimStart('-').TrimEnd('-'), "[-]+", "-").ToLower();
    }
    return string.Empty;
}


/// <summary>
/// All characters that do not match the patter, will get to this method, i.e. useful for unicode chars, because
/// .NET impl of regext do not handle unicode chars. So we use char.IsLetterOrDigit() which works nicely and we 
/// return what we approve and return - for everything else.
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
private static string CharacterTester(Match m)
{
    string x = m.ToString();
    if (x.Length > 0 && char.IsLetterOrDigit(x[0]))
    {
        return x.ToLower();
    }
    else
    {
        return "-";
    }
}
Lubomir Toshev
sumber
3
.NET regexes mendukung unicode dengan sangat baik. Anda harus menggunakan kelas karakter unicode misalnya \ p {L} untuk semua huruf. Lihat msdn.microsoft.com/en-us/library/20bw873z.aspx#CategoryOrBlock
TheCycoONE
1

Saya merasa sangat berguna untuk menyandikan url saya ke yang aman ketika saya mengembalikan nilai melalui ajax / php ke url yang kemudian dibaca oleh halaman itu lagi.

Output PHP dengan url encoder untuk karakter khusus &

//PHP returning the sucess info of ajax request
echo "".str_replace('&','%26',$_POST['name'])." category was changed";

//javascript sending the value to url
window.location.href='time.php?return=updated&val='+msg;

//javascript/php executing the function printing the value of the url,
//now with the text normally lost in space because of the reserved & character.

setTimeout("infoApp('updated','<?php echo $_GET['val'];?>');",360);

Semoga ada yang menemukan ekstrak kode kecil saya berguna! :)

DIY-Forum
sumber
0

Saya pikir Anda sedang mencari sesuatu seperti "Pengkodean URL" - pengkodean URL sehingga "aman" untuk digunakan di web:

Ini referensi untuk itu. Jika Anda tidak menginginkan karakter khusus, hapus saja yang memerlukan penyandian URL:

http://www.w3schools.com/TAGS/ref_urlencode.asp

Andy White
sumber
-4

Antara 3-50 karakter. Dapat berisi huruf kecil, angka dan karakter khusus - titik (.), Tanda hubung (-), garis bawah (_) dan dengan kecepatan (@).

Ramji
sumber
4
Ada referensi untuk itu?
dakab