tl;dr
--GCS kann den Inhaltstyp angeben
--Chrome versucht, "Text / Plain" in Shift-JIS anzuzeigen
--text / plain; charset = utf-8
ist nett
Erstellen Sie ein Objekt in Google Cloud Storage mit einem Skript, das dem folgenden ähnelt. Dies ist eine modifizierte Version des Codes googleapis / python-storage Example Usage zum Speichern von Zeichenfolgen, die Japanisch enthalten. Ich werde die Erstellung des Buckets und die Authentifizierung überspringen, da sie hier nicht relevant sind.
from google.cloud import storage
client = storage.Client()
bucket = client.get_bucket('bucket-id-here')
blob = bucket.get_blob('remote/path/to/file.json')
blob.upload_from_string('{"name": "japanisch"}')
Nach dem Ausführen des Skripts möchte ich mit dem Browser prüfen, ob das Objekt erstellt wurde.
Das Objekt scheint erfolgreich erstellt worden zu sein. Werfen wir einen Blick auf den Inhalt.
Google Cloud Storage verfügt über eine Funktion zum Generieren eines temporären Links. Sie können das Objekt herunterladen, indem Sie dem Link im Browser folgen.
Der Inhalt des Objekts wurde so verstümmelt. Diesmal ist dies das Problem.
file.json
{"name": "譌 ・ 譛 ャ 隱."}
Ich vergesse oft, Strings zu codieren und zu decodieren. Ich übergebe den str-Typ an "upload_from_string", aber ich werde prüfen, ob ich ihn nicht in UTF-8 usw. codieren musste.
Mit Blick auf den Code ist das, was upload_from_string
tut, einfach.
Auszug
def upload_from_string(Kürzung):
data = _to_bytes(data, encoding="utf-8")
string_buffer = BytesIO(data)
self.upload_from_file(Kürzung)
upload_from_file
aufVon oben sieht die Codierung der Zeichenfolge gut aus.
Übrigens, als ich mir die Objektinformationen im Browser ansah, fand ich einen Teil, der mich interessierte.
type="text/plain"
In GCS werden dem Objekt Metadaten zugewiesen. Es scheint, dass Sie den Antwortheader angeben können, wenn das Objekt in den Metadaten des Inhaltstyps aufgerufen wird. https://cloud.google.com/storage/docs/metadata#content-type
Standardmäßig sollte es "application / octat-stream" oder "application / x-www-form-urlencoded" sein, aber es scheint, dass dies "text / plain" ist. Ist das die Ursache?
Da ich angenommen habe, dass die Ursache für die verstümmelten Zeichen "Content-Type: text / plain" ist, werde ich einen Server einrichten und die Anzeige überprüfen, um sie von GCS zu trennen. Richten Sie einen Server ein, der einfach eine Zeichenfolge mit dem Inhaltstyp: text / plain mit Flasche zurückgibt.
server.py
from bottle import Bottle, HTTPResponse
import os
app = Bottle()
@app.route('/')
def serve():
r = HTTPResponse(status=200, body='Hoge')
r.set_header('Content-Type', 'text/plain')
return r
if __name__ == '__main__':
port = os.environ['PORT'] if 'PORT' in os.environ else '3000'
app.run(host='0.0.0.0', port=port)
Im Browser öffnen
Ich habe es reproduziert.
Übrigens, öffne es im Browser mit application / json
etc.
Wenn es sich um application / json
handelt, wird es korrekt angezeigt.
Aus dem oben Gesagten scheint es gut zu denken, dass "Content-Type: text / plain" die Ursache für verstümmelte Zeichen ist, unabhängig von GCS.
Es bleibt die Frage, warum der "Inhaltstyp", der in GCS standardmäßig "application / octat-stream" oder "application / x-www-form-urlencoded" sein sollte, jetzt "text / plain" war. Dies ist der Blob.upload_from_string des Moduls "google.cloud.storage", das zum Hochladen verwendet wird. # L1650-L1660) macht etwas falsch
Auszug
def upload_from_string(
self,
data,
content_type="text/plain",
client=None,
predefined_acl=None,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
if_metageneration_not_match=None,
):
Da das Standardargument von content_type "text / plain" ist, wird es als "Content-Type: text / plain" implementiert, sofern nicht anders angegeben.
In der Vergangenheit schien es, dass der Betrachter die Zeichenkodierung ändern konnte, aber jetzt scheint es, dass nur die automatische Inferenz des Browsers.
> document.characterSet
"Shift_JIS"
Ich versuche mit Shift_JIS anzuzeigen
Bis zu diesem Punkt haben wir festgestellt, dass die folgenden zwei Punkte die Ursachen für verstümmelte Zeichen sind.
Die Zeichen werden beim Anzeigen mit einem Browser verstümmelt, aber es gibt kein Problem bei der Verarbeitung mit einem Programm wie folgt.
from google.cloud import storage
client = storage.Client()
bucket = client.get_bucket('bucket-id-here')
blob = bucket.get_blob('remote/path/to/file.txt')
print(blob.download_as_string())
In meinem Fall wird das gespeicherte Objekt ohnehin von einem Programm gelesen, sodass es tatsächlich ein Problem war, wenn ich den Inhalt leicht sehen wollte. Es kann ein Problem sein, wenn Sie es als statisches Datei-Hosting verwenden.
Bei Verwendung von upload_from_string empfiehlt es sich, den Inhaltstyp anzugeben.
Für json können Sie application / json
verwenden, und für Text können Sie einen Zeichensatz wie text / plain; charset = utf-8
angeben, und Chrome liest ihn mit utf-8.
Ich war nicht vorsichtig, weil es sich in letzter Zeit selten ändert. Diesmal werden nicht viele Lektionen gelernt. Seien Sie also vorsichtig, wenn Sie Blob.upload_from_string verwenden.
Recommended Posts