I established a RESTful server, and I can get a simple string with my Chrome or IE using this URL: "http://localhost:8080/WebService/RESTful/getString"
But when using Dart, it always returns a error message:
"[object XMLHttpRequestProgressEvent]"
From the onError() callback method,
I'm sure that server returns a string with "text/plain" MIME type in Java.
Here is the code:
import 'dart:html';
void main() {
HtmlElement btn = document.body.querySelector("#btn");
btn.onClick.listen(onClick);
}
void onClick(Event v) {
var url = "http://localhost:8080/WebService/RESTful/getString";
HttpRequest.getString(url).then((str) {
window.alert(str.toString());
}, onError: (e) {
window.alert(e);
});
}
Who can help me ?
If you try to fetch resources from another server than the one your page was loaded from, this server needs to return CORS headers otherwise your browser refuses to fetch form this other server.
It depends on your server how this can be configured or added.
See for example
- How do you add CORS headers in Redstone interceptor?
- CORS with Dart, how do I get it to work?
Related
I am trying to send file from Client (Angular) to the NestJS same way like it is working now with Java-springboot API.
I am using POST method in NestJS but, unfortunatelly I am not able to got any data from the body :
here is the code :
#Post('/uploadExportFile')
uploadAttachment(#Req() req: Request, #Body() attachment: ArrayBuffer): any {
console.log(attachment);
return {};
}
content-type is set in header on Client side, I am not sure if I need to set content-types there ? Content type depends on file mimetype it should be (application/pdf/png/jpeg)..not multiform or what I need to do to achieve that attachment object will not return empty {} .
req.body is undefined
What I need to do with that file is to again change it back to Base64 (in angular it is in Base64) but Java API consumes only byte[] so I need to keep that like it is on FE.
any suggestions what is wrong in this "simple" code?
** EDIT **
====↓ EDIT ↓====
Solution: request.body is undefined is:
NestJS use as default body jsonBody, so in that case you have to override for specific routes that you want to use raw-body, and if raw-body is used insted of jsonBody, then the body from request is not undefined and it contain ArrayBuffer.
What you need to do is something like this;
Create rawBody middleware raw-body.middleware.ts
import { Injectable, NestMiddleware } from '#nestjs/common';
import { Request, Response } from 'express';
import * as bodyParser from 'body-parser';
#Injectable()
export class RawBodyMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => any) {
bodyParser.raw({type: '*/*'})(req, res, next);
}
}
app.module.ts
export class AppModule implements NestModule {
public configure(consumer: MiddlewareConsumer): void {
consumer
.apply(RawBodyMiddleware)
.forRoutes({
path: '/uploadExportFile',
method: RequestMethod.POST,
})
.apply(JsonBodyMiddleware)
.forRoutes('*');
}
}
and you need to disable bodyparser in main.ts
const app = await NestFactory.create(AppModule, { bodyParser: false })
in new version of NestJS is introduced new option raw-body but I have no possibility to test that https://docs.nestjs.com/faq/raw-body#raw-body
frist thing send the content-type application/x-www-form-urlencoded
and sure you have add UseInterceptors Like FileInterceptor
you can import FileInterceptor
if you need to get buffer try use file.buffer
import {FileInterceptor} from "#nestjs/platform-express";
#Post('upload')
#UseInterceptors(FileInterceptor('file'))
async upload(#Req() request: RequestWithUser, #UploadedFile() file) {
if (!file) {
throw new HttpException('File is required', HttpStatus.BAD_REQUEST);
}
// you have file
return await this.storageService.upload(file, request.user);
}
I tried looking for the solution in the forum but I was unable to find something similar to what I'm trying to achieve. I have a gateway script in an MPG which kinda looks like this:
session.INPUT.readAsJSON(function (error, json) {
if (error){
throw error;
} else {
var SAMLResponse = json['SAMLResponse'];
var RelayState = json['RelayState'];
var urlopen = require('urlopen');
var options = {
target: 'https://************.com/e32d32der2tj90g8h4',
method: 'POST',
headers: { 'HEADER_NAME' : 'VALUE'},
contentType: 'application/json',
timeout: 60,
sslClientProfile: 'ClientProfile',
data: {"SAMLResponse": SAMLResponse, "RelayState": RelayState}
};
urlopen.open(options, function(error, response) {
if (error) {
session.output.write("urlopen error: "+JSON.stringify(error));
} else {
var responseStatusCode = response.statusCode;
var responseReasonPhrase = response.reasonPhrase;
response.readAsBuffer(function(error, responseData){
if (error){
throw error;
} else {
session.output.write(responseData);
console.log(responseData);
}
});
}
});
}
});
I'm doing a POST request and the response I get from the urlopen function is an HTML page, how to I display the contents of that page in my browser? I need that to initiate a process flow. am I going in the wrong direction here? what's the best way to POST to a URI and display it's response in DataPower?
with regards to my experience with DataPower, I just started learning, So I might not be familiar with many of the concepts.
Thanks in Advance!
session.INPUT.readAsJSON() would indicate that you are receiving JSON data as the input (from the POST).
Since you are building this in a Multi-Protocol Gateway (MPGW) you need to set the Response type to non-xml if the response is HTML and if there is no backend call being made (other than the url-open()) you also must set the skip-backside=1 variable.
Is the scenario as:
JSON HTTP Request -> [MPGW] -> url-open() -> Backend server --|
HTTP Response <-----------------------------------------|
Or:
JSON HTTP Request -> [MPGW] -> url-open() --| (skip-backside)
HTTP Response <------------------------|
If there is no backend call I would recommend building this in a XML Firewall (XMLFW) service instead and set it to "loopback" and non-xml.
If there is a backend and that is where you are sending your HTML from the url-open() then only MPGW Response type needs to be set to non-xml.
If it is the second option the you can just set the payload and headers in GWS and just call the target (https://************.com/e32d32der2tj90g8h4) as teh MPGW backside connection, no need for the url-open().
$http in my AngularJS project not able to recognize 40X(401,403,405...) errors on iOS.
I am using 1.2.10 AngularJS version and Cordova version 3.4.0.
Below is the code I am using:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials,successCallback,errorCallback){
$http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
successCallback(response.data);
console.log("Success------"+JSON.stringify(response))
},function(data, status, headers, config){
errorCallback(data);
console.log("Error------"+JSON.stringify(data)+" "+status)
})
}
}
});
hello.loginUser($rootScope.encodedUserCredencials,function(persons) {
// success handler
}, function(data) {
// error handler
console.log(data.status+"===="+status)
});
data.status is returning 0 and status returns undefined.
Please help me to resolve this issue.
Tried to include the domain in whitelist on IOS.But no solution :( It still gives the same response.
But the same code works absolutely fine in Android.
Please help me to resolve this issue.
Thanks in advance :)
So you r using the $http from angular. Do you use the error callback or the second function in the then callback ?
Example
$http.get("someUrl")
.success(function(response){}) // if http code == 200
.error(function(response){}) // else
Or with then, that can take 2 functions. The first is the onSuccess, the second the onError function.
$http.get("someUrl")
.then(function(response){
// if http code == 200
},
function(response){
// else
});
The response parameter does also contain the error codes.
Consider using a $httpInterceptor to handle all errorcodes at the same place, instead handling them in every http callback.
UPDATE:
It seems, that the angular doc is incomplete/wrong for the success callback.
It doesnt pass 4 parameter there. It does pass a response object that contains all the information about request+response and the passed data.
Update to the edit:
Dont write callbacks by yourself. Use angular promises:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials){
return $http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
return response.data;
},function(response){
return response;
});
}
}
});
hello.loginUser($rootScope.encodedUserCredencials)
.then(function(persons) { // success handler
}, function(data) { // error handler
console.log(data);
});
Try this and tell me if the console.log logs something.
I had exactly the same problem. Cordova app, angular js, IPhone and 401 requests are not received in angular js http interceptor. They work fine on android devices.
My finding was that IPhone browser is handling those at a higher lever and trying to use WWW-Authenticate information to do authentication. This is why the response does not get to angular.
The only solution I found, was to change my service to return 400 instead of 401 in case of an api request. In this case I return 400 with an error message that I handle on client side.
I hope this helps.
My issue with the 403 status code was that my backend returned a response with status 403 but the body of a response did not contain a JSON string. It contained just a string - Authentication Failed.
The rejection variable was an object Error.
I encoded the body and the rejection variable contains a valid response error object.
To handle HTTP errors I use interceptors.
$httpProvider.interceptors.push(function($q, $location, redirect, HTTP_CODES) {
return {
'responseError': function(rejection) {
if (rejection.status === HTTP_CODES.FORBIDDEN) {
redirect('/login', $location.url());
}
return $q.reject(rejection);
}
};
});
I am very new to the dart programming any help is appreciated.
void main() {
var server = new HttpServer();
server.listen('127.0.0.1', 8080);
server.
addRequestHandler(
accept(HttpRequest function) => acceptInput(request, response), handler);
}
I want to add the function below to the request handler.
server.addrequestHandler()
I would like to do this so that I can add many request handlers as such including one for websockets
A sample or a tutorial would be very helpful.
I want to keep each handler in a separate function just for simplicity.
void acceptInput(HttpRequest request,HttpResponse response){
print(request.connectionInfo.toString());
print(request.queryParameters.toString());
response.outputStream.write('Hello dude'.charCodes);
response.outputStream.close();
}
Note:I know my void main code is wrong I need help to make it correct so that it incorporates the acceptInput Function.
Actually, you're really close.
Try this:
var server = new HttpServer();
server.addRequestHandler(
(req) => req.path == '/save',
handleSave);
server.addRequestHandler(
(req) => req.path == '/delete',
handleDelete);
server.defaultRequestHandler = new StaticFileHandler(basePath).onRequest;
Where handleSave and handleDelete are just functions, like:
handleSave(HttpRequest req, HttpResponse resp) {
// ...
}
Here is the code for a web server that serves files and handles web socket connections:
https://github.com/dart-lang/web-components-code-lab/blob/master/step04/bin/chat_server.dart
Does that answer your question?
You should check out at my implementation of Express.dart which is an Express-like web framework that fits in a single file so it's an easy read.
Check out the HttpServer docs to see the correct signatures for each method. This is the API for addRequestHandler:
abstract addRequestHandler(
bool matcher(HttpRequest request),
void handler(HttpRequest request, HttpResponse response)
)
The first parameter is whether this should handle the request, whilst the 2nd argument is the handler that will handle the request if the matcher is true.
So a Http app in Dart would look like:
var server = new HttpServer();
server.addRequestHandler(
(HttpRequest req) => true,
acceptInput);
server.listen('127.0.0.1', 8080);
I have an URL to encode on my java serveur and then to decode with javascript.
I try to retrieve a String I send in param with java. It is an error message from a form validation function.
I do it like that (server side. Worker.doValidateForm() return a String) :
response.sendRedirect(URLEncoder.encode("form.html?" + Worker.doValidateForm(), "ISO-8859-1"));
Then, in my javascript, I do that :
function retrieveParam() {
var error = window.location.search;
decodeURIComponent(error);
if(error)
alert(error);
}
Of course it doesn't work. Not the same encoding I guess.
So my question is : which method can I use in Java to be able to decode my URL with javascript ?
It's ok ! I have found a solution.
Server side with Java :
URI uri = null;
try {
uri = new URI("http", "localhost:8080", "/PrizeWheel/form.html", Worker.doValidateForm(), null);
} catch (URISyntaxException e) {
this.log.error("class Worker / method doPost:", e); // Just writing the error in my log file
}
String url = uri.toASCIIString();
response.sendRedirect(url);
And in the Javascript (function called in the onload of the redirected page) :
function retrieveParam() {
var error = decodeURI(window.location.search).substring(1);
if(error)
alert(error);
}
You don't use URLEncoder to encode URLs, it us used to encode form data to application/x-www-form-urlencoded MIME format. You use URIEncoder instead, see http://contextroot.blogspot.fi/2012/04/encoding-urls-in-java-is-quite-trivial.html