SseEmiter를 반환하는 웹 서비스가 있습니다. 로드 바를 프로그래밍하는 데 사용하고 있지만…받는 방법은 다음과 같습니다.
static async synchronize(component: Vue) {
let xhr = new XMLHttpRequest();
xhr.open('PATCH', 'myUrl.com');
xhr.responseType = "text"
xhr.setRequestHeader('Authorization', 'mySessionToken')
xhr.setRequestHeader("Content-Type", "text/event-stream")
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response)
} else {
reject({status: this.status, statusText: xhr.statusText})
}
}
xhr.onerror = function () {reject({status: this.status, statusText: xhr.statusText})}
xhr.onreadystatechange = function() {if (xhr.readyState == XMLHttpRequest.DONE) { alert(xhr.responseText) }}
xhr.onprogress = function(onEvent) {
console.log(xhr.response)
}
xhr.send()
}
지금은 이게 먹히긴 하는데…그xhr.response
data는 이것을 문자열로 반환합니다.
data:"{ hello: '1' }" data:"{ hello: '2' }" data:"{ hello: '3' }" data:"{ hello: '4' }" data:"{ hello: '5' }" data:"{ hello: '6' }" data:"{ hello: '7' }" data:"{ hello: '8' }" data:"{ hello: '9' }" data:"{ hello: '10' }" data:"{ hello: '11' }" data:"{ hello: '12' }" data:"{ hello: '13' }" data:"{ hello: '14' }" data:"{ hello: '15' }" data:"{ hello: '16' }" data:"{ hello: '17' }" data:"{ hello: '18' }" data:"{ hello: '19' }"
//And so on until it reach 100.
이것은 문제가 되지 않는 것처럼 보이지만, 실제로는 방출된 각 이벤트에 대해 전체 상태 이력이 반환되고 각 값에 따라 더 커집니다.
즉, 이러한 응답의 마지막 값만 얻을 수 있는 방법은 없는 것입니까? Json.parse()
응답 형식이 json으로 되어 있지 않기 때문에 에러가 발생하고 있습니다.
SseEmitter의 출처가 되는 Web 서비스의 코드를 공유할 수 있습니다만, 이 문제를 해결할 필요는 없다고 생각합니다.도와주셔서 감사합니다!
질문에 대한 답변
이 문자열은 JSON 문자열이므로 해석할 수 있습니다.
const data = JSON.parse(xhr.response.replace("data:", "")) // { hello: 'xx' }
왜 사용하세요?XMLHttpRequest
SSE를 소비하다EventSource
?
어쨌든, 좋은 이유가 있다고 가정한다면, 당신은 좀 더 많은 일을 해야 합니다.
먼저 새로운 함수를 만들어 최신 데이터 블록을 가져옵니다.이것에 문자열이 아닌 JS 오브젝트를 지정합니다.
function onData(d){ console.log(d) }
그리고 지금까지 처리한 내용을 추적하고 새로운 부분을 잘라내는 것이 기본 아이디어입니다.
let lastLen = 0
xhr.onprogress = function(onEvent) {
const s = xhr.response.slice(lastLen+5)
lastLen = xhr.response.length
onData(JSON.parse(s)) }
만약 그랬다면xhr.response.slice(lastLen)
마지막 “데이터: {…}” 블록(선행 및/또는 후행 공백으로 구분됨)에 따라+5
“데이터:” 부분을 통과시키는 것입니다.
이건 좀 깨지기 쉬운데.선두 공백이 있는 경우+5
틀릴 거야또한 두 개 이상의 “데이터: {…}” 블록이 함께 도착합니다.이 경우 다음과 같은 작업을 수행해야 합니다.const parts = xhr.response.slice(lastLen).split("nn")
다음으로 각 엔트리를 처리합니다.parts
.
이를 올바르게 수행하려면 EventSource 표준 또는 폴리필 라이브러리 중 하나의 코드를 검토해야 합니다.또는 단순히 이러한 폴리필 라이브러리 중 하나를 사용합니다;-)